Changeset 9434


Ignore:
Timestamp:
2007-10-24T20:06:24+02:00 (9 years ago)
Author:
nbd
Message:

add updated motorola-bin.c file from #2483 (by D. Hugh Redelmeier)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/firmware-utils/src/motorola-bin.c

    r3156 r9434  
    44 * Copyright (C) 2005-2006 Mike Baker, 
    55 *                         Imre Kaloz <kaloz@openwrt.org> 
     6 *                         D. Hugh Redelmeier 
    67 *                         OpenWrt.org 
    78 * 
     
    2526 
    2627/* 
     28 * Motorola's firmware flashing code requires an extra header. 
     29 * The header is eight bytes (see struct motorola below). 
     30 * This program will take a firmware file and create a new one 
     31 * with this header: 
     32 *      motorola-bin --wr850g WR850G_V403.stripped.trx WR850G_V403.trx 
     33 * 
     34 * Note: Motorola's firmware is distributed with this header. 
     35 * If you need to flash Motorola firmware on a router running OpenWRT, 
     36 * you will to remove this header.  Use the --strip flag: 
     37 *      motorola-bin --strip WR850G_V403.trx WR850G_V403.stripped.trx 
     38 */ 
     39 
     40/* 
    2741 * February 1, 2006 
    2842 * 
     
    3246#include <stdio.h> 
    3347#include <stdlib.h> 
     48#include <stddef.h> 
    3449#include <unistd.h> 
     50#include <errno.h> 
    3551#include <fcntl.h> 
    3652#include <sys/mman.h> 
    3753#include <string.h> 
    3854#include <netinet/in.h> 
    39  
    40 unsigned long *crc32; 
    41  
    42 void init_crc32() 
    43 { 
    44     unsigned long crc; 
    45     unsigned long poly = ntohl(0x2083b8ed); 
    46     int n, bit; 
    47     if ((crc32 = (unsigned long *) malloc(256 * sizeof(unsigned long))) == (void *)-1) { 
    48        perror("malloc"); 
    49        exit(1); 
    50     } 
    51     for (n = 0; n < 256; n++) { 
    52         crc = (unsigned long) n; 
    53         for (bit = 0; bit < 8; bit++) 
    54             crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); 
    55         crc32[n] = crc; 
    56     } 
    57 } 
    58  
    59 unsigned int crc32buf(char *buf, size_t len) 
    60 { 
    61     unsigned int crc = 0xFFFFFFFF; 
    62     for (; len; len--, buf++) 
    63         crc = crc32[(crc ^ *buf) & 0xff] ^ (crc >> 8); 
    64     return crc; 
     55#include <inttypes.h> 
     56 
     57#define BPB 8 /* bits/byte */ 
     58 
     59static uint32_t crc32[1<<BPB]; 
     60 
     61static void init_crc32() 
     62{ 
     63        const uint32_t poly = ntohl(0x2083b8ed); 
     64        int n; 
     65 
     66        for (n = 0; n < 1<<BPB; n++) { 
     67                uint32_t crc = n; 
     68                int bit; 
     69 
     70                for (bit = 0; bit < BPB; bit++) 
     71                        crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); 
     72                crc32[n] = crc; 
     73        } 
     74} 
     75 
     76static uint32_t crc32buf(unsigned char *buf, size_t len) 
     77{ 
     78        uint32_t crc = 0xFFFFFFFF; 
     79 
     80        for (; len; len--, buf++) 
     81                crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB); 
     82        return crc; 
    6583} 
    6684 
    6785struct motorola { 
    68         unsigned int crc;       // crc32 of the remainder 
    69         unsigned int flags;     // unknown, 105770* 
    70         char *trx;              // standard trx 
     86        uint32_t crc;   // crc32 of the remainder 
     87        uint32_t flags; // unknown, 105770* 
    7188}; 
    7289 
    73 void usage(void) __attribute__ (( __noreturn__ )); 
    74  
    75 void usage(void) 
    76 { 
    77         printf("Usage: motorola-bin [-device] [trxfile] [binfile]\n\n"); 
    78         printf("Known devices: 1 - WR850G | 2 - WA840G | 3 - WE800G\n"); 
     90static const struct model { 
     91        char digit;     /* a digit signifying model (historical) */ 
     92        const char *name; 
     93        uint32_t flags; 
     94} models[] = { 
     95        { '1', "WR850G", 0x10577050LU }, 
     96        { '2', "WA840G", 0x10577040LU }, 
     97        { '3', "WE800G", 0x10577000LU }, 
     98        { '\0', NULL, 0 } 
     99}; 
     100 
     101static void usage(const char *) __attribute__ (( __noreturn__ )); 
     102 
     103static void usage(const char *mess) 
     104{ 
     105        const struct model *m; 
     106 
     107        fprintf(stderr, "Error: %s\n", mess); 
     108        fprintf(stderr, "Usage: motorola-bin -device|--strip infile outfile\n"); 
     109        fprintf(stderr, "Known devices: "); 
     110 
     111        for (m = models; m->digit != '\0'; m++) 
     112                fprintf(stderr, " %c - %s", m->digit, m->name); 
     113 
     114        fprintf(stderr, "\n"); 
    79115        exit(1); 
    80116} 
     
    82118int main(int argc, char **argv) 
    83119{ 
    84         unsigned int len; 
     120        off_t len;      // of original firmware 
    85121        int fd; 
    86         int c; 
    87         void *trx; 
    88         struct motorola *firmware; 
     122        void *trx;      // pointer to original firmware (mmmapped) 
     123        struct motorola *firmware;      // pionter to prefix + copy of original firmware 
     124        uint32_t flags; 
    89125 
    90126        // verify parameters 
    91127 
    92         if (argc!=4) 
     128        if (argc != 4) 
     129                usage("wrong number of arguments"); 
     130 
     131        // mmap trx file 
     132        if ((fd = open(argv[2], O_RDONLY))  < 0 
     133        || (len = lseek(fd, 0, SEEK_END)) < 0 
     134        || (trx = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) 
     135        || close(fd) < 0) 
    93136        { 
    94         usage(); 
    95         } 
    96  
    97         // mmap trx file 
    98         if (((fd = open(argv[2], O_RDONLY))  < 0) 
    99         || ((len = lseek(fd, 0, SEEK_END)) < 0) 
    100         || ((trx = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1)) 
    101         || (close(fd) < 0)) { 
    102                 perror("open/malloc"); 
     137                fprintf(stderr, "Error loading file %s: %s\n", argv[2], strerror(errno)); 
    103138                exit(1); 
    104139        } 
    105          
    106         // create a firmware image in memory 
    107         // and copy the trx to it 
    108         firmware = malloc(len+8); 
    109         memcpy(&firmware->trx,trx,len); 
     140 
     141        init_crc32(); 
     142 
     143        if (strcmp(argv[1], "--strip") == 0) 
     144        { 
     145                const char *ugh = NULL; 
     146 
     147                if (len < sizeof(struct motorola)) { 
     148                        ugh = "input file too short"; 
     149                } else { 
     150                        const struct model *m; 
     151 
     152                        firmware = trx; 
     153                        if (htonl(crc32buf(trx + offsetof(struct motorola, flags), len - offsetof(struct motorola, flags))) != firmware->crc) 
     154                                ugh = "Invalid CRC"; 
     155                        for (m = models; ; m++) { 
     156                                if (m->digit == '\0') { 
     157                                        if (ugh == NULL) 
     158                                                ugh = "unrecognized flags field"; 
     159                                        break; 
     160                                } 
     161                                if (firmware->flags == htonl(m->flags)) { 
     162                                        fprintf(stderr, "Firmware for Motorola %s\n", m->name); 
     163                                        break; 
     164                                } 
     165                        } 
     166                } 
     167 
     168                if (ugh != NULL) { 
     169                        fprintf(stderr, "%s\n", ugh); 
     170                        exit(3); 
     171                } else { 
     172                        // all is well, write the file without the prefix 
     173                        if ((fd = open(argv[3], O_CREAT|O_WRONLY,0644)) < 0 
     174                        || write(fd, trx + sizeof(struct motorola), len - sizeof(struct motorola)) !=  len - sizeof(struct motorola) 
     175                        || close(fd) < 0) 
     176                        { 
     177                                fprintf(stderr, "Error storing file %s: %s\n", argv[3], strerror(errno)); 
     178                                exit(2); 
     179                        } 
     180                } 
     181                 
     182        } else { 
     183                // setup the firmware flags magic number 
     184                const struct model *m; 
     185                const char *df = argv[1]; 
     186 
     187                if (*df != '-') 
     188                        usage("first argument must start with -"); 
     189                if (*++df == '-') 
     190                        ++df;   /* allow but don't require second - */ 
     191 
     192                for (m = models; ; m++) { 
     193                        if (m->digit == '\0') 
     194                                usage("unrecognized device specified"); 
     195                        if ((df[0] == m->digit && df[1] == '\0') || strcasecmp(df, m->name) == 0) { 
     196                                flags = m->flags; 
     197                                break; 
     198                        } 
     199                } 
     200 
     201 
     202                // create a firmware image in memory 
     203                // and copy the trx to it 
     204                firmware = malloc(sizeof(struct motorola) + len); 
     205                memcpy(&firmware[1], trx, len); 
     206 
     207                // setup the motorola headers 
     208                firmware->flags = htonl(flags); 
     209 
     210                // CRC of flags + firmware 
     211                firmware->crc = htonl(crc32buf((unsigned char *)&firmware->flags, sizeof(firmware->flags) + len)); 
     212 
     213                // write the firmware 
     214                if ((fd = open(argv[3], O_CREAT|O_WRONLY,0644)) < 0 
     215                || write(fd, firmware, sizeof(struct motorola) + len) != sizeof(struct motorola) + len 
     216                || close(fd) < 0) 
     217                { 
     218                        fprintf(stderr, "Error storing file %s: %s\n", argv[3], strerror(errno)); 
     219                        exit(2); 
     220                } 
     221 
     222                free(firmware); 
     223        } 
     224 
    110225        munmap(trx,len); 
    111226 
    112         // setup the motorola headers 
    113         init_crc32(); 
    114  
    115         // setup the firmware magic 
    116  
    117         while ((c = getopt(argc, argv, "123")) !=-1) { 
    118                 switch (c) { 
    119                         case '1': 
    120                                 firmware->flags = ntohl(0x10577050); // Motorola WR850G 
    121                                 break; 
    122                         case '2': 
    123                                 firmware->flags = ntohl(0x10577040); // Motorola WA840G 
    124                                 break; 
    125                         case '3': 
    126                                 firmware->flags = ntohl(0x10577000); // Motorola WE800G 
    127                                 break; 
    128                         default: 
    129                                 usage(); 
    130                 } 
    131         } 
    132  
    133         firmware->crc   = htonl(crc32buf((char *)&firmware->flags,len+4)); 
    134  
    135         // write the firmware 
    136         if (((fd = open(argv[3], O_CREAT|O_WRONLY,0644)) < 0) 
    137         || (write(fd,firmware,len+8) != len+8) 
    138         || (close(fd) < 0)) { 
    139                 perror("write"); 
    140                 exit(-1); 
    141         } 
    142  
    143         free(firmware); 
    144  
    145227        return 0; 
    146228} 
Note: See TracChangeset for help on using the changeset viewer.