source: tt-loader/main.c

Last change on this file was 16, checked in by guillaume, 15 years ago

Publication tt-loader v0.2.2

File size: 27.6 KB
Line 
1/*
2 * tt-loader - A system loader through USB derived from OMAP Flash Loader
3 *
4 * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
5 * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 */
22
23#include <stdio.h>
24#include <string.h>
25#include <unistd.h>
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <sys/times.h>
29#include <fcntl.h>
30#include <usb.h>
31#include <endian.h>
32#include <byteswap.h>
33#include <errno.h>
34
35extern unsigned long crc32( unsigned long crc, char* buf, unsigned int len);
36
37/*
38 * Here Vendor/Product detected for the target device
39 */
40#define OMAP_VENDOR             0x0451
41#define OMAP_PRODUCT    0x3f01
42
43#define IN_EP   0x81
44#define OUT_EP  0x02
45
46/*
47 * Length of memory dump lines
48 */
49#define DUMP_LINE_SIZE          32
50
51struct mem_file {
52        void *content ;
53        int size ;
54        char *filename ;
55};
56
57/*
58 * MAX_SIZE is the maximum size of the 2nd.bin program
59 */
60#define MAX_SIZE        65536
61#define CHUNK_SIZE      8192
62static char     buffer[MAX_SIZE + 128];
63static int      buffsize = 0;
64static struct mem_file cmdfile = { NULL, 0, NULL };
65static double btime ;
66static double ticks ;
67
68#define log2(X,Y)       fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,(Y))
69#define log3(X,Y,Z)     fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,(Y),(Z))
70#define log4(W,X,Y,Z)   fprintf(stderr, "%9.3f: "W,((double)times(NULL)-btime)/ticks,(X),(Y),(Z))
71
72#if __BYTE_ORDER == __LITTLE_ENDIAN
73# define cpu_to_le32(x) (x)
74# define le32_to_cpu(x) (x)
75#else
76# define cpu_to_le32(x) bswap_32 (x)
77# define le32_to_cpu(x) bswap_32 (x)
78#endif
79
80static inline double chrono ()
81{
82        return ((double)times(NULL)-btime)/ticks ;
83}
84
85static inline void log1 ( const char *msg )
86{
87        fprintf(stderr, "%9.3f: ", chrono());
88        return (void)fprintf(stderr, msg);
89}
90
91static inline unsigned round_up (unsigned v, unsigned d)
92{
93        v+= --d;
94        return v & ~d;
95}
96
97static int stringcopy( char * dest, const char *src, int max )
98{
99        char *tmp = dest, *s = (char *) src;
100        int count = 0 ;
101       
102        while (count++ < max)
103                if (!(*tmp++ = *s++ ))
104                        break ;
105       
106        return count;
107}
108
109static int send_cmd (usb_dev_handle *handle, const char req, const char *src)
110{
111        int     res, len = 5 ;
112       
113        buffer[0]= 'T';
114        buffer[1]= 'I';
115        buffer[2]= 'S';
116        buffer[3]= req ;
117        buffer[4]= '\0' ;
118        if (src!=NULL)
119                len += stringcopy (&buffer[4], src, 60);
120        else
121                len = 4 ;
122        buffer[63]= '\0' ; // truncate anyway
123       
124        res= usb_bulk_write (handle, OUT_EP, buffer, len, 1000);
125        if (res < len)
126        {
127                log2("Error in usb_bulk_write during send_char: %d/4\n", res);
128                return 0;
129        }
130       
131        return 1;
132}
133
134static int send_binsize (usb_dev_handle *handle, int size)
135{
136        int     res;
137        buffer[0]= 'T';
138        buffer[1]= 'I';
139        buffer[2]= 'S';
140        buffer[3]= 's';
141        *(u_int32_t *) &buffer[4]= cpu_to_le32 ( size < CHUNK_SIZE ? size : CHUNK_SIZE );
142       
143        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
144        if (res < 8)
145        {
146                log2("Error in usb_bulk_write during send_binsize: %d/8\n", res);
147                return 0;
148        }
149       
150        return 1;
151}
152
153static int send_word (usb_dev_handle *handle, const char req, int word)
154{
155        int     res;
156        buffer[0]= 'T';
157        buffer[1]= 'I';
158        buffer[2]= 'S';
159        buffer[3]= req;
160        *(u_int32_t *) &buffer[4]= cpu_to_le32 (word);
161       
162        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
163        if (res < 8)
164        {
165                log2("Error in usb_bulk_write: %d/8\n", res);
166                return 0;
167        }
168       
169        return 1;
170}
171
172static int send_poke (usb_dev_handle *handle, int poke)
173{
174        int     res;
175        buffer[0]= 'T';
176        buffer[1]= 'I';
177        buffer[2]= 'S';
178        buffer[3]= 'p';
179        *(u_int32_t *) &buffer[4]= cpu_to_le32 (poke);
180       
181        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
182        if (res < 8)
183        {
184                log2("Error in usb_bulk_write: %d/8\n", res);
185                return 0;
186        }
187       
188        return 1;
189}
190
191static struct mem_file readfile( char *filename )
192{
193        struct mem_file toread = { NULL, 0, NULL };
194        int fd= open (filename, O_RDONLY);
195       
196        if (fd < 0)
197        {
198                log3("Error opening %s file (err=%d)\n", filename, errno);
199                return toread;
200        }
201       
202        toread.size = lseek (fd, 0, SEEK_END);
203        if (toread.size < 0  ||  lseek (fd, 0, SEEK_SET) < 0)
204        {
205                log3("Error with lseek other %s file (err=%d)\n", filename, errno);
206                close (fd);
207                return toread;
208        }
209       
210        toread.content= malloc (round_up (toread.size, 4));
211        if (toread.content == NULL)
212        {
213                log2("Out of memory requesting %d bytes\n", toread.size);
214                close (fd);
215                return toread;
216        }
217       
218        if ((toread.size= read (fd, toread.content, toread.size)) < 0)
219        {
220                log3("Error reading %s file (err=%d)\n", filename, errno);
221                close (fd);
222                return toread;
223        }
224       
225        close (fd);
226       
227        return toread ;
228}
229
230static int savefile( char *filename, struct mem_file buffer )
231{
232        int fd= creat (filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH );
233       
234        if (fd < 0)
235        {
236                log3("Error opening %s file for writing (err=%d)\n", filename, errno);
237                return 1;
238        }
239       
240        if (buffer.size != write (fd, buffer.content, buffer.size))
241        {
242                log3("Error writing %s file (err=%d)\n", filename, errno);
243                close (fd);
244                return 1;
245        }
246       
247        close (fd);
248       
249        return 0 ;
250}
251
252static int process (usb_dev_handle *handle)
253{
254        int     err = -1 ;
255       
256        log1("OMAP found, trying to configure it\n");
257       
258        for (;;)
259        {
260                err= -usb_set_configuration (handle, 1);
261                if (err == 0)
262                        break;
263
264// TODO: l'erreur ENODEV est peut-être juste un problème temporaire dans le noyau
265// et peut réclamer de ré-essayer, y compris plus tard dans le code
266                if (err == ENODEV)
267                {
268                        log1("OMAP error, aborting\n");
269                        return 1;
270                }
271                else if (err == EPERM)
272                {
273                        log1("USB error, you don't have rights to open OMAP device, aborting\n");
274                        return 1;
275                }
276                else if (err == ETIME)
277                {
278                        log1("OMAP error, you need to reboot your OMAP device, aborting\n");
279                        return 1;
280                }
281                else
282                        log2("OMAP error %d, retrying\n",err);
283               
284                usleep (100000);
285        }
286       
287        err = usb_claim_interface (handle, 0);
288        if ( err < 0)
289                log2("Error in usb_claim_interface (%d)\n",err);
290        else
291        {
292                char inbuff[MAX_SIZE + 128];
293                int     insize= usb_bulk_read (handle, IN_EP, inbuff, sizeof (inbuff), 1000);
294               
295                if (insize < 48)
296                        log2("Error in usb_bulk_read: %d\n", insize);
297                else
298                {
299                        log1("OMAP 1st boot contacted, sending 2nd boot\n");
300                       
301                        memcpy (&buffer[20], inbuff, 44);
302                        memcpy (&buffer[80], inbuff, 48);
303                       
304                        char *p = buffer;
305                        int     size= buffsize;
306                        while (size > 0)
307                        {
308                                int chunksize = size < CHUNK_SIZE ? size : CHUNK_SIZE ;
309                                int     outsize = usb_bulk_write (handle, OUT_EP, p, chunksize, 1000);
310                                if (outsize < chunksize)
311                                {
312                                        log3("Error in usb_bulk_write: %d/%d\n", outsize,chunksize);
313                                        break;
314                                }
315
316                                p+= chunksize;
317                                size-= chunksize;
318                        }
319                       
320                        if (size <= 0)
321                        {
322                                log2("Sent %d bytes to OMAP\n",buffsize);
323                               
324                                p= NULL;
325                                size= 0;
326                               
327                                int     res=1, sz= 0, loop= 1, cmd=0, ftag=0, finfo=0, fline=0 ;
328                                int vendor, device, info ;
329                                char *cmdp = cmdfile.content ;
330                                struct mem_file current = { NULL, 0, NULL };
331                               
332                                err = 1 ; // Set error by default
333                               
334                                while (loop != 0)
335                                {
336                                        if (loop<0) loop++ ; // Avoid infinite loop
337                                       
338                                        if (res>0 || ftag)
339                                                res= usb_bulk_read (handle, IN_EP,
340                                                        inbuff, sizeof (inbuff), 5000);
341                                       
342                                        if (res < 0)
343                                        {
344                                                log2("Error in usb_bulk_read: %d\n",res);
345                                                break;
346                                        }
347                                       
348                                        if (ftag)
349                                        {
350                                                switch (ftag)
351                                                {
352                                                        case 0xaaaa0001:
353                                                                // A string should be in the buffer with length still set in finfo
354                                                                if ( res != finfo)
355                                                                {
356                                                                        log3("Error waiting string from flasher program: length = %d vs %d expected\n", res, finfo);
357                                                                        break ;
358                                                                }
359                                                                // Fix the string just in case
360                                                                inbuff[res] = '\0' ;
361                                                                if (fline)
362                                                                        fprintf(stderr, "%s",inbuff);
363                                                                else
364                                                                        log2("Flasher: %s", inbuff);
365                                                                if ( inbuff[res-1] == '\n' )
366                                                                        fline = 0 ;
367                                                                else
368                                                                        fline ++ ;
369                                                                break ;
370                                                        case 0xaaaa0002:
371                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
372                                                                break ;
373                                                        case 0xaaaa0003:
374                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
375                                                                log2("Flasher: NAND read = 0x%08X\n", finfo);
376                                                                break ;
377                                                        case 0xaaaa0004:
378                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
379                                                                log2("Flasher: NAND size = 0x%08X\n", finfo);
380                                                                break ;
381                                                        case 0xaaaa0005:
382                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
383                                                                log2("Flasher: Error code = %d\n", finfo);
384                                                                err = - finfo ; // Will quit on error
385                                                                break ;
386                                                        case 0xaaaa0006:
387                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
388                                                                log2("Flasher: NAND remain = 0x%08X\n", finfo);
389                                                                break ;
390                                                }
391                                                ftag = 0 ;
392                                                continue ;
393                                        }
394                                       
395                                        if (err<0)
396                                        {
397                                                err = -err ; // Keep err as positive number
398                                                if (send_cmd (handle,'e',NULL))
399                                                        log1("Asking stop\n");
400                                                else
401                                                        log1("Can't ask to stop\n");
402                                                break ; // Leave loop
403                                        }
404
405                                        if (res >= 4)
406                                        {
407                                                if (inbuff[0] == 'T'  &&  inbuff[1] == 'I'  &&
408                                                        inbuff[2] == 'S')
409                                                {
410                                                        switch (inbuff[3])
411                                                        {
412                                                        case 'f':
413                                                                // Target claims a file
414                                                                log3("OMAP File asked: %s (%d bytes)\n", &inbuff[4], size);
415                                                                if (!send_binsize (handle, size))
416                                                                        loop = 0 ; // Just quit on error
417                                                                break;
418                                                               
419                                                        case 'o':
420                                                                // Update upload file buffer offset
421                                                                sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
422                                                                p+= sz;
423                                                                size-= sz;
424                                                                //log3("OMAP seek %d to 0x%08lX\n", sz, (long)p-(long)current.content);                                         // DEBUG
425                                                                if (size > 0  &&  !send_binsize (handle, size))
426                                                                        loop = 0 ; // Just quit on error
427                                                                if (size==0)
428                                                                        res = 0 ;
429                                                                break;
430                                                               
431                                                        case 'n':
432                                                                // Upload a requested size chunk from the file buffer
433                                                                sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
434                                                                //log2("OMAP read %d\n", sz);                                   // DEBUG
435                                                                res= usb_bulk_write (handle, OUT_EP, p, sz, 1000);
436                                                                if (res < sz)
437                                                                {
438                                                                        log3("Error in usb_bulk_write: %d/%d\n", res, sz);
439                                                                        loop = 0 ; // Just quit on error
440                                                                }
441                                                                break;
442                                                               
443                                                        case 'I':
444                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
445                                                                log2("OMAP integer info: %d\n", info);
446                                                                break;
447                                                               
448                                                        case 'x':
449                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
450                                                                u_int32_t len = le32_to_cpu (*(u_int32_t *) &inbuff[8]);
451                                                                u_int32_t crc = le32_to_cpu (*(u_int32_t *) &inbuff[12]);
452                                                                log4("OMAP crc32 computing: pos 0x%08x/0x%08x, current crc32 0x%08X\n",info,len,crc);
453                                                                break;
454                                                               
455                                                        case 'A':
456                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
457                                                                log2("OMAP address info: 0x%08X\n", info);
458                                                                break;
459                                                               
460                                                        case 'C':
461                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
462                                                                log2("OMAP crc32 found: 0x%08X\n", info);
463                                                                break;
464                                                               
465                                                        case 'i':
466                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
467                                                                log2("OMAP Info returned: 0x%08X\n", info);
468                                                                res = 0 ; // Target is waiting a new command
469                                                                break;
470                                                               
471                                                        case 'v':
472                                                                vendor= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
473                                                                log2("Flash Vendor found: 0x%02X\n", vendor);
474                                                                break;
475                                                               
476                                                        case 'd':
477                                                                device= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
478                                                                log2("Flash Device found: 0x%02X\n", device);
479                                                                break;
480                                                               
481                                                        case 'm':
482                                                                log2("OMAP Message: %s\n", &inbuff[4]);
483                                                                break;
484                                                               
485                                                        case 'D':
486                                                                if (!current.content)
487                                                                {
488                                                                        log1("Can't dump memory without buffer\n");
489                                                                        loop = 0 ;
490                                                                        break ;
491                                                                }
492                                                                res -= 4 ;
493                                                                if (res < 1)
494                                                                {
495                                                                        log2("Received empty memory dump (res=%d)\n",res);
496                                                                        // reset buffer size anyway
497                                                                        current.size = 0 ;
498                                                                        res = 0 ; // Target is waiting a new command
499                                                                       
500                                                                } else {
501                                                                        if (res > size)
502                                                                        {
503                                                                                log2("Can't dump %d bytes as buffer is full\n",res);
504                                                                                loop = 0 ;
505                                                                                break ;
506                                                                        }
507                                                                        memcpy(p,&inbuff[4],res);
508                                                                        p += res ;
509                                                                        size -= res ;
510                                                                }
511                                                                if ( size == 0 )
512                                                                {
513                                                                        log2("%d bytes dumped to buffer\n",current.size);
514                                                                        res = 0 ; // Target is waiting a new command
515                                                                }
516                                                                break;
517                                                               
518                                                        case 'M':
519                                                                sz = 0 ;
520                                                                res -= 4 ;
521                                                                while (sz<res)
522                                                                {
523                                                                        log2("0x%08X | ",info);
524                                                                       
525                                                                        loop=0 ;
526                                                                        while (++loop<=DUMP_LINE_SIZE)
527                                                                                fprintf (stderr,"%02hhX", inbuff[3+sz+loop]);
528                                                                        fprintf (stderr, " |");
529                                                                       
530                                                                        loop=0 ;
531                                                                        while (++loop<=DUMP_LINE_SIZE)
532                                                                                if ((int)inbuff[3+sz+loop]>=0x20 && (int)inbuff[3+sz+loop]<0x7f)
533                                                                                        fprintf (stderr,"%c", inbuff[3+sz+loop]);
534                                                                                else
535                                                                                        fprintf (stderr,".");
536                                                                       
537                                                                        fprintf (stderr,"|\n");
538                                                                       
539                                                                        info += DUMP_LINE_SIZE;
540                                                                        sz += DUMP_LINE_SIZE;
541                                                                }
542                                                                res = 0 ; // Target is waiting a new command
543                                                                break;
544                                                               
545                                                        case 'r':
546                                                                log2("OMAP is ready: %s\n", &inbuff[4]);
547                                                                res = 0 ; // Target is waiting a new command
548                                                                break;
549
550                                                        case 'b':
551                                                                // Boot command has been received
552                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
553                                                                log2("OMAP is booting at address: 0x%08X\n", info);
554                                                                loop = err = res = 0 ; // Quit now
555                                                                break;
556
557                                                        default:
558                                                                log2("Unknown packet type '%c'\n", inbuff[3]);
559                                                                break;
560                                                        }
561                                                } else
562                                                {
563                                                        info = le32_to_cpu (*(u_int32_t *) inbuff);
564                                                        switch (info)
565                                                        {
566                                                                case 0xaaaa0001:
567                                                                case 0xaaaa0002:
568                                                                case 0xaaaa0003:
569                                                                case 0xaaaa0004:
570                                                                case 0xaaaa0005:
571                                                                case 0xaaaa0006:
572                                                                        ftag = info ;
573                                                                        break ;
574                                                                case 0xff555580:
575                                                                        log1("Flasher: Command finished\n");
576                                                                        break ;
577                                                                default:
578                                                                        // Fix the string just in case
579                                                                        inbuff[res] = '\0' ;
580                                                                        // Strip final EOL in the string
581                                                                        if ( inbuff[res-1] == '\n' )
582                                                                                inbuff[res-1] = '\0' ;
583                                                                        if (res==4)
584                                                                                log3("Got: %s (0x%08X)\n", inbuff, info);
585                                                                        else
586                                                                                log2("Got: %s\n", inbuff);
587                                                        }
588                                                }
589                                        }
590                                        else
591                                        {
592                                                // Manage commands
593                                                if (cmd + 1 >= cmdfile.size)
594                                                {
595                                                        if (loop>0) {
596                                                                log1("Command file read finished\n");
597                                                                loop = 0 ;
598                                                        }
599                                                       
600                                                } else {
601                                                        // res < 4
602                                                        //log2("Next command is '%c'\n", cmdp[cmd]);                    // DEBUG
603                                                        switch (cmdp[cmd])
604                                                        {
605                                                        case 'D': // Save downloaded memory to a file still specified
606                                                                if (current.filename == NULL)
607                                                                {
608                                                                        log1("Can't save without a file specified with 'F' command\n");
609                                                                        loop = 0 ; // Just quit on error
610                                                                        break ;
611                                                                }
612                                                                if (current.content == NULL)
613                                                                {
614                                                                        log2("Can't save without download buffer to file '%s'\n",current.filename);
615                                                                        loop = 0 ; // Just quit on error
616                                                                        break ;
617                                                                }
618                                                                if (current.size==0)
619                                                                        log2("Nothing to save, file %s is still up to date\n",current.filename);
620                                                                else if (savefile(current.filename, current)==0)
621                                                                {
622                                                                        info = crc32(0,current.content,current.size);
623                                                                        log3("Downloaded memory saved to file %s with CRC32=0x%08X\n",current.filename,info);
624                                                                } else
625                                                                {
626                                                                        log2("Can't save downloaded memory saved to file %s\n",current.filename);
627                                                                        // Just quit on error
628                                                                        loop = 0 ;
629                                                                }
630                                                                // Release memory
631                                                                free((void *)current.content);
632                                                                free((void *)current.filename);
633                                                                current.content = NULL ;
634                                                                current.filename = NULL ;
635                                                                res -- ;
636                                                                break;
637                                                        case 'd': // Save downloaded memory to a file
638                                                                cmd += 2 ;
639                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
640                                                                {
641                                                                        log1("Bad 'd' format in command download\n");
642                                                                        break ;
643                                                                }
644                                                                if (current.content == NULL)
645                                                                {
646                                                                        log2("Can't save without download buffer to file '%s'\n",&cmdp[cmd]);
647                                                                        loop = 0 ; // Just quit on error
648                                                                        break ;
649                                                                }
650                                                                if (current.size==0)
651                                                                        log2("Nothing to save, file %s is still up to date\n",&cmdp[cmd]);
652                                                                else if (savefile(&cmdp[cmd], current)==0)
653                                                                {
654                                                                        info = crc32(0,current.content,current.size);
655                                                                        log3("Downloaded memory saved to file %s with CRC32=0x%08X\n",&cmdp[cmd],info);
656                                                                } else
657                                                                {
658                                                                        log2("Can't save downloaded memory saved to file %s\n",&cmdp[cmd]);
659                                                                        // Just quit on error
660                                                                        loop = 0 ;
661                                                                }
662                                                                // Release memory
663                                                                free((void *)current.content);
664                                                                current.content = NULL ;
665                                                                res -- ;
666                                                                break;
667                                                        case 'f': // Put a file to be uploaded in a memory buffer
668                                                                cmd += 2 ;
669                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
670                                                                {
671                                                                        log1("Bad 'f' format in command file\n");
672                                                                        break ;
673                                                                }
674                                                                // Free previously used memory buffer
675                                                                if (current.content != NULL)
676                                                                        free((void *)current.content);
677                                                                current = readfile(&cmdp[cmd]);
678                                                                if (current.content == NULL)
679                                                                {
680                                                                        log2("Can't read file '%s'\n",&cmdp[cmd]);
681                                                                        loop = 0 ; // Just quit on error
682                                                                        break ;
683                                                                }
684                                                                p = current.content ;
685                                                                size = current.size ;
686                                                                // Say to OMAP target it can reclaim the file
687                                                                if (send_cmd (handle,'f',(const char *)&cmdp[cmd]))
688                                                                        log1("File loaded and ready for upload\n");
689                                                                else
690                                                                {
691                                                                        log1("Can't say we are ready for upload\n");
692                                                                        // Just quit on error
693                                                                        loop = 0 ;
694                                                                }
695                                                                break;
696                                                        case 'F': // Set a filename that would be loaded to check crc and saved
697                                                                cmd += 2 ;
698                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
699                                                                {
700                                                                        log1("Bad 'F' format in command file\n");
701                                                                        break ;
702                                                                }
703                                                                // Free previously used memory buffer
704                                                                if (current.filename != NULL)
705                                                                        free((void *)current.filename);
706                                                                info = strlen(&cmdp[cmd]);
707                                                                if (info == 0)
708                                                                {
709                                                                        log2("Can't read filename '%s' length\n",&cmdp[cmd]);
710                                                                        loop = 0 ; // Just quit on error
711                                                                        break ;
712                                                                }
713                                                                current.filename = malloc (++info);
714                                                                if (current.filename == NULL)
715                                                                {
716                                                                        log2("Out of memory requesting %d bytes\n", info);
717                                                                        loop = 0 ; // Just quit on error
718                                                                        break ;
719                                                                }
720                                                                if (info!=stringcopy(current.filename,&cmdp[cmd],info))
721                                                                {
722                                                                        log2("Can't read filename '%s'\n",&cmdp[cmd]);
723                                                                        loop = 0 ; // Just quit on error
724                                                                        break ;
725                                                                }
726                                                                // still read next command
727                                                                res -- ;
728                                                                break;
729                                                        case 'C': // Get a CRC32 and send it to target
730                                                                cmd += 2 ;
731                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
732                                                                {
733                                                                        log2("Can't read crc32 '%s'\n",&cmdp[cmd]);
734                                                                        loop = 0 ; // Just quit on error
735                                                                        break ;
736                                                                }
737                                                                // compute the current CRC32 if a file is referenced and exists
738                                                                if (!info && current.filename != NULL)
739                                                                {
740                                                                        struct mem_file loader = readfile(current.filename);
741                                                                        if (loader.content == NULL)
742                                                                        {
743                                                                                log2("Can't read file '%s', will be initialized with target\n",current.filename);
744                                                                        } else
745                                                                        {
746                                                                                log3("Checking CRC32 of %d bytes from %s file\n",loader.size,current.filename);
747                                                                                info = crc32(0,loader.content,loader.size);
748                                                                                free(loader.content);
749                                                                        }
750                                                                }
751                                                                if (send_word (handle, 'C', info))
752                                                                        log2("Sending crc32 0x%02X\n", info);
753                                                                else
754                                                                {
755                                                                        log2("Can't send crc32 0x%02X\n", info);
756                                                                        loop = 0 ; // Just quit on error
757                                                                }
758                                                                break;
759                                                        case 'a': // Get an address and send it to target
760                                                                cmd += 2 ;
761                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
762                                                                {
763                                                                        log2("Can't read address '%s'\n",&cmdp[cmd]);
764                                                                        loop = 0 ; // Just quit on error
765                                                                        break ;
766                                                                }
767                                                                if (send_word (handle, 'a', info))
768                                                                        log2("Sending address 0x%02X\n", info);
769                                                                else
770                                                                {
771                                                                        log2("Can't send address 0x%02X\n", info);
772                                                                        loop = 0 ; // Just quit on error
773                                                                }
774                                                                break;
775                                                        case 'm': // Get a size in kB and ask a memory download
776                                                                cmd += 2 ;
777                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
778                                                                {
779                                                                        log2("Can't read size '%s'\n",&cmdp[cmd]);
780                                                                        loop = 0 ; // Just quit on error
781                                                                        break ;
782                                                                }
783                                                                // size unit is kbytes
784                                                                size = info * 1024 ;
785                                                                // Free previously used memory buffer
786                                                                if (current.content != NULL)
787                                                                        free((void *)current.content);
788                                                                current.size = size ;
789                                                                p = malloc (round_up (size, 4));
790                                                                if ( p == NULL)
791                                                                {
792                                                                        log2("Out of memory requesting %d bytes\n", round_up (size, 4));
793                                                                        loop=0 ;
794                                                                        break ;
795                                                                }
796                                                                current.content = p ;
797                                                                if (!(send_word (handle,'m',size)))
798                                                                {
799                                                                        log2("Can't ask to download %d bytes from memory\n",size);
800                                                                        loop = 0 ; // Just quit on error
801                                                                } else
802                                                                        log2("Allocated %d kBytes to download memory\n",info);
803                                                                break;
804                                                        case 'M': // Ask memory dump
805                                                                if (!(send_cmd (handle,'M',NULL)))
806                                                                {
807                                                                        log1("Can't ask to read memory\n");
808                                                                        loop = 0 ; // Just quit on error
809                                                                }
810                                                                break;
811                                                        case 'P': // Ask a peek onto the address
812                                                                if (!(send_cmd (handle,'P',NULL)))
813                                                                {
814                                                                        log1("Can't ask to peek memory\n");
815                                                                        loop = 0 ; // Just quit on error
816                                                                }
817                                                                break;
818                                                        case 'S': // Ask to change stack to the last given address
819                                                                if (send_cmd (handle,'S',NULL))
820                                                                        log1("Asking stack relocate\n");
821                                                                else
822                                                                {
823                                                                        log1("Can't ask to relocate stack\n");
824                                                                        loop = 0 ; // Just quit on error
825                                                                }
826                                                                break;
827                                                        case 'c': // Make a call to the last given address
828                                                                if (send_cmd (handle,'c',NULL))
829                                                                        log1("Asking function call\n");
830                                                                else
831                                                                {
832                                                                        log1("Can't ask to call a function\n");
833                                                                        loop = 0 ; // Just quit on error
834                                                                }
835                                                                break;
836                                                        case 'b': // Boot the target by just branching to the last given address
837                                                                if (send_cmd (handle,'b',NULL)) {
838                                                                        log1("Asking boot\n");
839                                                                        // Quit now witout error set
840                                                                        loop = err = 0 ;
841                                                                        cmd = cmdfile.size ;
842                                                                        res = 1 ;
843                                                                } else
844                                                                {
845                                                                        log1("Can't ask to boot\n");
846                                                                        loop = 0 ; // Just quit on error
847                                                                }
848                                                                break;
849                                                        case 'e': // End of commands
850                                                                log1("Commands read and sent\n");
851                                                                if (send_cmd (handle,'e',NULL))
852                                                                        log1("Asking stop\n");
853                                                                else
854                                                                        log1("Can't ask to stop\n");
855                                                                // Quit now witout error set
856                                                                loop = err = 0 ;
857                                                                cmd = cmdfile.size ;
858                                                                res = 1 ;
859                                                                break ;
860                                                        case 'k': // Boot a linux kernel to the last given address
861                                                                cmd += 2 ;
862                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
863                                                                {
864                                                                        log2("Can't read mach id '%s'\n",&cmdp[cmd]);
865                                                                        loop = -10 ; // Just quit on error
866                                                                        break ;
867                                                                }
868                                                                if (send_word (handle,'k', info)) {
869                                                                        log1("Asking kernel to boot\n");
870                                                                        // Quit now witout error set
871                                                                        loop = err = 0 ;
872                                                                        cmd = cmdfile.size ;
873                                                                        res = 1 ;
874                                                                } else
875                                                                {
876                                                                        log1("Can't ask to boot a kernel\n");
877                                                                        loop = 0 ; // Just quit on error
878                                                                }
879                                                                break;
880                                                        case 'p': // poke
881                                                                cmd += 2 ;
882                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
883                                                                {
884                                                                        log2("Can't read value to poke '%s'\n",&cmdp[cmd]);
885                                                                        loop = 0 ; // Just quit on error
886                                                                        break ;
887                                                                }
888                                                                if (send_poke (handle, info))
889                                                                        log2("Sending poke 0x%08X\n", info);
890                                                                else
891                                                                {
892                                                                        log2("Can't send poke 0x%08X\n", info);
893                                                                        loop = 0 ; // Just quit on error
894                                                                }
895                                                                break;
896                                                        case '#':
897                                                                cmd += 2 ;
898                                                                log2("%s\n", &cmdp[cmd]);
899                                                        case '/':
900                                                                // skip comments
901                                                                res -- ;
902                                                                break ;
903                                                               
904                                                        default:
905                                                                log2("Unknown command type '%c'\n",cmdp[cmd]);
906                                                                break;
907                                                        }
908                                                        // kind of readline
909                                                        while (cmdp[++cmd] != '\0' && cmd < cmdfile.size);
910                                                        // point to next line
911                                                        while (cmdp[++cmd] == '\0' && cmd < cmdfile.size);
912                                                        res ++ ;
913                                                }
914                                        }
915                                }
916                                // Free used memory buffer
917                                if (current.content != NULL)
918                                        free((void *)current.content);
919                                if (current.filename != NULL)
920                                        free((void *)current.filename);
921                        }
922                }
923        }
924       
925        if (err>=0) {
926                log1("Releasing usb interface\n");
927                err = usb_release_interface (handle, 0);
928                if (err < 0)
929                        log2("Error in usb_release_interface (%d)\n",err);
930                log1("Released usb interface\n");
931        }
932       
933        return err ;
934}
935
936enum {
937        ARG_PROGNAME,
938        ARG_2NDFILE,
939        ARG_CMDFILE,
940        NUM_ARGS
941};
942
943int main (int argc, char *argv[])
944{
945        int     size, err=-1;
946        btime = (double) times(NULL);
947        ticks = (double) sysconf(_SC_CLK_TCK) / 1000 ;
948       
949        if (argc < NUM_ARGS)
950        {
951                fprintf(stderr, "Usage: %s <2nd_boot_file> <command_file>\n", argv[ARG_PROGNAME]);
952                return 1;
953        }
954       
955        memset (buffer, 0, 128);
956       
957        u_int32_t *p= (u_int32_t *) buffer;
958        p[0x00]= cpu_to_le32 (0xf0030002);
959       
960        int     fd= open (argv[ARG_2NDFILE], O_RDONLY);
961        if (fd < 0)
962        {
963                log1("open 2nd boot file\n");
964                return 1;
965        }
966        else
967        {
968                size= read (fd, &buffer[128], MAX_SIZE);
969                if (size < 0)
970                {
971                        log1("read 2nd boot file\n");
972                        close (fd);
973                        return 1;
974                }
975               
976                close (fd);
977                if (size < 1024)
978                {
979                        log2("2ndfile is too small! (%d bytes)\n", size);
980                        return 1;
981                }
982        }
983       
984        size= round_up (size, 4);
985       
986        p[0x21]= cpu_to_le32 (size - 0x40);
987       
988        p[0x01]= cpu_to_le32 (size);
989        p[0x02]= cpu_to_le32 (size);
990        p[0x03]= cpu_to_le32 (size);
991        p[0x10]= cpu_to_le32 (size);
992        p[0x11]= cpu_to_le32 (size);
993        p[0x12]= cpu_to_le32 (size);
994       
995        buffsize= 128 + round_up (size, 4);
996       
997        cmdfile = readfile(argv[ARG_CMDFILE]);
998        if (cmdfile.content == NULL)
999        {
1000                log1("open cmdfile\n");
1001                return 1;
1002        } else {
1003                int i = 0 ;
1004                char *cmdbuffer = (char *)cmdfile.content ;
1005                do {
1006                        if (cmdbuffer[i] == '\n' || cmdbuffer[i] == '\r' || cmdbuffer[i] == ';')
1007                                cmdbuffer[i] = '\0' ;
1008                        // Skip comment line
1009                        if (cmdbuffer[i] == '/') {
1010                                while ( i++ < cmdfile.size ) {
1011                                        if (cmdbuffer[i] == '\n' || cmdbuffer[i] == '\r') {
1012                                                i-- ;
1013                                                break ;
1014                                        }
1015                                }
1016                        }
1017                } while ( i++ < cmdfile.size );
1018        }
1019       
1020        usb_init ();
1021        usb_find_busses ();
1022       
1023        log1("Try to found OMAP730-USB connection\n");
1024       
1025        int     n= usb_find_devices ();
1026        if (n)
1027        {
1028                log1("Searching OMAP730-USB connection...\n");
1029                while ( chrono() < 30000 )
1030                {
1031                        struct usb_bus  *bus;
1032                        for (bus= usb_get_busses (); bus; bus= bus->next)
1033                        {
1034                                struct usb_device       *dev;
1035                                                       
1036                                for (dev= bus->devices; dev; dev= dev->next)
1037                                {
1038                                        usb_dev_handle  *handle;
1039                                        if (dev->descriptor.idVendor == OMAP_VENDOR  &&
1040                                                dev->descriptor.idProduct == OMAP_PRODUCT  &&
1041                                                (handle= usb_open (dev)) != NULL)
1042                                        {
1043                                                log1("Found OMAP730-USB connection\n");
1044                                                int res= process (handle);
1045// TODO Ajouter la déconnexion de la device avec une option pour la garder (cas de renvoi de console)
1046                                                usb_close (handle);
1047                                                if (res == 0) {
1048                                                        log1("OMAP730-USB connection processed\n");
1049                                                        err = 0 ;
1050                                                        break ;
1051                                                       
1052                                                } else {
1053                                                        log1("OMAP730-USB processing failed\n");
1054                                                        err = 1 ;
1055                                                        break ;
1056                                                }
1057                                        }
1058                                }
1059                                if ( err >= 0 )
1060                                        break ;
1061                        }
1062                       
1063                        if ( err >= 0 )
1064                                break ;
1065                       
1066                        while ( ! usb_find_devices() && chrono() < 5000 )
1067                                usleep(10000);
1068                }
1069               
1070                if (err<0)
1071                        log1("Time-out: No OMAP-730 found\n");
1072       
1073               
1074        } else {
1075                log1("No USB bus found\n");
1076        }
1077       
1078        // Free memory
1079        if (cmdfile.content!=NULL)
1080                free((void *)cmdfile.content);
1081
1082        return 1 ;
1083}
Note: See TracBrowser for help on using the repository browser.