Changeset 2419


Ignore:
Timestamp:
2005-11-11T16:28:42+01:00 (11 years ago)
Author:
nbd
Message:

add mtd cleanup, fix #17

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/openwrt/package/mtd/mtd.c

    r1842 r2419  
    33 * 
    44 * Copyright (C) 2005 Waldemar Brodkorb <wbx@dass-it.de>, 
    5  *                    Felix Fietkau <nbd@vd-s.ath.cx> 
     5 *                        Felix Fietkau <nbd@openwrt.org> 
    66 * 
    77 * This program is free software; you can redistribute it and/or 
     
    1717 * You should have received a copy of the GNU General Public License 
    1818 * along with this program; if not, write to the Free Software 
    19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
     19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
    2020 * 
    2121 * $Id$ 
    2222 * 
    23  * code is based on linux-mtd example code 
     23 * The code is based on the linux-mtd examples. 
    2424 */ 
    2525 
     
    4444 
    4545#define TRX_MAGIC       0x30524448      /* "HDR0" */ 
    46 #define BUFSIZE (10 * 1024) 
     46#define BUFSIZE (16 * 1024) 
    4747#define MAX_ARGS 8 
     48 
     49#define DEBUG 
    4850 
    4951struct trx_header { 
     
    5557}; 
    5658 
     59char buf[BUFSIZE]; 
     60int buflen; 
     61 
    5762int 
    58 trx_check(const char *trxfile, const char *mtd, int force) 
     63trx_check(int imagefd, const char *mtd) 
    5964{ 
    6065        struct mtd_info_user mtdInfo; 
    61         int trxfd, fd; 
     66        int fd; 
    6267        size_t count; 
    63         struct trx_header trx; 
     68        struct trx_header *trx = (struct trx_header *) buf; 
    6469        struct stat trxstat; 
    6570 
    66         trxfd = open(trxfile,O_RDONLY);  
    67         if(trxfd < 0) { 
    68                 fprintf(stderr, "Could not open image: %s\n", trxfile); 
    69                 exit(1); 
    70         } 
    71  
    72         if (fstat(trxfd,&trxstat) < 0) { 
    73                 fprintf(stderr, "Could not get image file status: %s\n", trxfile); 
    74                 close(trxfd); 
    75                 exit(1); 
    76         } 
    77  
    78         if (force == 0) { 
    79                 count = read(trxfd, &trx, sizeof(struct trx_header)); 
    80                 if (count < sizeof(struct trx_header)) { 
    81                         fprintf(stderr, "Could not get trx header, file too small (%ld bytes)\n", count); 
    82                         close(trxfd); 
    83                         exit(1); 
    84                 } 
    85  
    86                 if (trx.magic != TRX_MAGIC || trx.len < sizeof(struct trx_header)) { 
    87                         fprintf(stderr, "Bad trx header\n"); 
    88                         fprintf(stderr, "If this is a firmware in bin format, like some of the\n" 
    89                                         "original firmware files are, use following command to convert to trx:\n" 
    90                                         "dd if=firmware.bin of=firmware.trx bs=32 skip=1\n"); 
    91                         close(trxfd); 
    92                         exit(1); 
    93                 } 
    94          
    95                 lseek(trxfd, 0, SEEK_SET); 
     71        buflen = read(imagefd, buf, sizeof(struct trx_header)); 
     72        if (buflen < sizeof(struct trx_header)) { 
     73                fprintf(stderr, "Could not get trx header, file too small (%ld bytes)\n", buflen); 
     74                return 0; 
     75        } 
     76 
     77        if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) { 
     78                fprintf(stderr, "Bad trx header\n"); 
     79                fprintf(stderr, "If this is a firmware in bin format, like some of the\n" 
     80                                "original firmware files are, use following command to convert to trx:\n" 
     81                                "dd if=firmware.bin of=firmware.trx bs=32 skip=1\n"); 
     82                return 0; 
    9683        } 
    9784 
    9885        /* check if image fits to mtd device */ 
    99  
    10086        fd = mtd_open(mtd, O_RDWR); 
    10187        if(fd < 0) { 
     
    10692        if(ioctl(fd, MEMGETINFO, &mtdInfo)) { 
    10793                fprintf(stderr, "Could not get MTD device info from %s\n", mtd); 
    108                 close(fd); 
    109                 exit(1); 
    110         } 
    111                  
    112         if(mtdInfo.size < trxstat.st_size) { 
     94                exit(1); 
     95        } 
     96                 
     97        if(mtdInfo.size < trx->len) { 
    11398                fprintf(stderr, "Image too big for partition: %s\n", mtd); 
    114                 close(trxfd); 
    115                 close(fd); 
    116                 exit(1); 
     99                close(fd); 
     100                return 0; 
    117101        }        
    118102         
    119         printf("Writing %s to %s ...\n", trxfile, mtd); 
     103        return 1; 
     104} 
     105 
     106int mtd_check(char *mtd) 
     107{ 
     108        struct mtd_info_user mtdInfo; 
     109        int fd; 
     110 
     111        fd = mtd_open(mtd, O_RDWR); 
     112        if(fd < 0) { 
     113                fprintf(stderr, "Could not open mtd device: %s\n", mtd); 
     114                return 0; 
     115        } 
     116 
     117        if(ioctl(fd, MEMGETINFO, &mtdInfo)) { 
     118                fprintf(stderr, "Could not get MTD device info from %s\n", mtd); 
     119                close(fd); 
     120                return 0; 
     121        } 
    120122 
    121123        close(fd); 
    122  
    123         return(trxfd); 
     124        return 1; 
    124125} 
    125126 
     
    143144        } 
    144145 
    145         printf("Unlocking %s ...\n", mtd); 
     146        fprintf(stderr, "Unlocking %s ...\n", mtd); 
    146147        mtdLockInfo.start = 0; 
    147148        mtdLockInfo.length = mtdInfo.size; 
     
    195196        } 
    196197 
    197         printf("Erasing %s ...\n", mtd); 
     198        fprintf(stderr, "Erasing %s ...\n", mtd); 
    198199        mtdEraseInfo.length = mtdInfo.erasesize; 
    199200 
     
    216217 
    217218int 
    218 mtd_write(int trxfd, const char *mtd) 
    219 { 
    220         int fd,i; 
    221         size_t result,size,written; 
     219mtd_write(int imagefd, const char *mtd) 
     220{ 
     221        int fd, i, result; 
     222        size_t r, w, e; 
    222223        struct mtd_info_user mtdInfo; 
    223224        struct erase_info_user mtdEraseInfo; 
    224         unsigned char src[BUFSIZE],dest[BUFSIZE]; 
    225         struct stat trxstat; 
    226  
    227         if (fstat(trxfd,&trxstat) < 0) { 
    228                 fprintf(stderr, "Could not get trx image file status\n"); 
    229                 close(trxfd); 
    230                 exit(1); 
    231         } 
    232225 
    233226        fd = mtd_open(mtd, O_RDWR); 
     
    243236        } 
    244237                 
    245         mtdEraseInfo.start = 0; 
    246         mtdEraseInfo.length = trxstat.st_size & ~(mtdInfo.erasesize -1); 
    247         if(trxstat.st_size % mtdInfo.erasesize) mtdEraseInfo.length += mtdInfo.erasesize; 
    248  
    249         /* erase the chunk */ 
    250         if (ioctl (fd,MEMERASE,&mtdEraseInfo) < 0) { 
    251                 fprintf(stderr, "Erasing mtd failed: %s\n", mtd); 
    252                 exit(1); 
    253         } 
    254          
    255         size = trxstat.st_size; 
    256         i = BUFSIZE; 
    257         written = 0; 
    258  
    259         while (size) { 
    260                 if (size < BUFSIZE) i = size; 
    261                 read(trxfd,src,i); 
    262                 result = write(fd,src,i); 
    263                 if (i != result) { 
     238        r = w = e = 0; 
     239        fprintf(stderr, " [ ]"); 
     240 
     241        for (;;) { 
     242                /* buffer may contain data already (from trx check) */ 
     243                r = buflen; 
     244                r += read(imagefd, buf + buflen, BUFSIZE - buflen); 
     245                w += r; 
     246 
     247                /* EOF */ 
     248                if (r <= 0) break; 
     249 
     250                /* need to erase the next block before writing data to it */ 
     251                while (w > e) { 
     252                        mtdEraseInfo.start = e; 
     253                        mtdEraseInfo.length = mtdInfo.erasesize; 
     254 
     255                        fprintf(stderr, "\b\b\b[e]"); 
     256                        /* erase the chunk */ 
     257                        if (ioctl (fd,MEMERASE,&mtdEraseInfo) < 0) { 
     258                                fprintf(stderr, "Erasing mtd failed: %s\n", mtd); 
     259                                exit(1); 
     260                        } 
     261                        e += mtdInfo.erasesize; 
     262                } 
     263                 
     264                fprintf(stderr, "\b\b\b[w]"); 
     265                 
     266                if ((result = write(fd, buf, r)) < r) { 
    264267                        if (result < 0) { 
    265                                 fprintf(stderr,"Error while writing image"); 
     268                                fprintf(stderr, "Error writing image.\n"); 
    266269                                exit(1); 
    267                         } 
    268                         fprintf(stderr,"Error writing image"); 
    269                         exit(1); 
    270                 } 
    271                 written += i; 
    272                 size -= i; 
    273         } 
     270                        } else { 
     271                                fprintf(stderr, "Insufficient space.\n"); 
     272                                exit(1); 
     273                        } 
     274                } 
     275                 
     276                buflen = 0; 
     277        } 
     278        fprintf(stderr, "\b\b\b\b"); 
    274279         
    275280        return 0; 
     
    278283void usage(void) 
    279284{ 
    280         printf("Usage: mtd [<options> ...] <command> [<arguments> ...] <device>\n\n" 
     285        fprintf(stderr, "Usage: mtd [<options> ...] <command> [<arguments> ...] <device>\n\n" 
    281286        "The device is in the format of mtdX (eg: mtd4) or its label.\n" 
    282287        "mtd recognizes these commands:\n" 
    283         "       unlock                  unlock the device\n" 
    284         "       erase                   erase all data on device\n" 
    285         "       write <imagefile>       write imagefile to device\n" 
     288        "        unlock                  unlock the device\n" 
     289        "        erase                   erase all data on device\n" 
     290        "        write <imagefile>|-     write <imagefile> (use - for stdin) to device\n" 
    286291        "Following options are available:\n" 
    287         "       -r                      reboot after successful command\n" 
    288         "       -f                      force write without trx checks\n" 
    289         "       -e <device>             erase <device> before executing the command\n\n" 
     292        "        -r                      reboot after successful command\n" 
     293        "        -f                      force write without trx checks\n" 
     294        "        -e <device>             erase <device> before executing the command\n\n" 
    290295        "Example: To write linux.trx to mtd4 labeled as linux and reboot afterwards\n" 
    291296        "         mtd -r write linux.trx linux\n\n"); 
     
    295300int main (int argc, char **argv) 
    296301{ 
    297         int ch, i, boot, unlock, trxfd, force; 
    298         char *erase[MAX_ARGS], *device; 
     302        int ch, i, boot, unlock, imagefd, force; 
     303        char *erase[MAX_ARGS], *device, *imagefile; 
    299304        enum { 
    300305                CMD_ERASE, 
     
    306311        boot = 0; 
    307312        force = 0; 
     313        buflen = 0; 
    308314 
    309315        while ((ch = getopt(argc, argv, "fre:")) != -1) 
     
    343349                cmd = CMD_WRITE; 
    344350                device = argv[2]; 
    345                 /* check trx file before erasing or writing anything */ 
    346                 trxfd = trx_check(argv[1], device, force); 
     351         
     352                if (strcmp(argv[1], "-") == 0) { 
     353                        imagefile = "<stdin>"; 
     354                        imagefd = 0; 
     355                } else { 
     356                        imagefile = argv[1]; 
     357                        if ((imagefd = open(argv[1], O_RDONLY)) < 0) { 
     358                                fprintf(stderr, "Couldn't open image file: %s!\n", imagefile); 
     359                                exit(1); 
     360                        } 
     361                } 
     362         
     363                if (system("grep Broadcom /proc/cpuinfo >&- >&-") != 0) { 
     364                        /* check trx file before erasing or writing anything */ 
     365                        if (!trx_check(imagefd, device)) { 
     366                                fprintf(stderr, "TRX check failed!\n"); 
     367                                if (!force) 
     368                                        exit(1); 
     369                        } 
     370                } else { 
     371                        if (!mtd_check(device)) { 
     372                                fprintf(stderr, "Can't open device for writing!\n"); 
     373                                exit(1); 
     374                        } 
     375                } 
    347376        } else { 
    348377                usage(); 
     
    350379 
    351380        sync(); 
    352  
     381         
    353382        i = 0; 
    354383        while (erase[i] != NULL) { 
     
    367396                        break; 
    368397                case CMD_WRITE: 
    369                         mtd_write(trxfd, device); 
     398                        fprintf(stderr, "Writing from %s to %s ... ", imagefile, device); 
     399                        mtd_write(imagefd, device); 
     400                        fprintf(stderr, "\n"); 
    370401                        break; 
    371402        } 
Note: See TracChangeset for help on using the changeset viewer.