Changeset 17659


Ignore:
Timestamp:
2009-09-21T11:58:41+02:00 (7 years ago)
Author:
nbd
Message:

mtd: add support for rewriting the fis table layout on redboot based systems

Location:
trunk/package/mtd
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/mtd/Makefile

    r17554 r17659  
    1313 
    1414PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME) 
     15STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS) 
    1516 
    1617include $(INCLUDE_DIR)/package.mk 
     
    3435target=$(firstword $(subst -, ,$(BOARD))) 
    3536 
    36 define Build/Compile 
    37         $(MAKE) -C $(PKG_BUILD_DIR) \ 
    38                 $(TARGET_CONFIGURE_OPTS) \ 
    39                 TARGET=$(target) \ 
    40                 CFLAGS="$(TARGET_CFLAGS) -Dtarget_$(target)=1 -Wall" 
    41 endef 
     37MAKE_FLAGS += TARGET="$(target)" 
     38TARGET_CFLAGS += -Dtarget_$(target)=1 -Wall 
     39 
     40ifdef CONFIG_MTD_REDBOOT_PARTS 
     41  MAKE_FLAGS += FIS_SUPPORT=1 
     42  TARGET_CFLAGS += -DFIS_SUPPORT=1 
     43endif 
    4244 
    4345define Package/mtd/install 
  • trunk/package/mtd/src/Makefile

    r12655 r17659  
    66obj.brcm47xx = $(obj.brcm) 
    77 
     8ifdef FIS_SUPPORT 
     9  obj += fis.o 
     10endif 
     11 
    812mtd: $(obj) $(obj.$(TARGET)) 
    913clean: 
  • trunk/package/mtd/src/mtd.c

    r17522 r17659  
    4444#include <linux/reboot.h> 
    4545#include "mtd-api.h" 
     46#include "fis.h" 
    4647#include "mtd.h" 
    4748 
     
    120121        mtdEraseInfo.length = erasesize; 
    121122        ioctl(fd, MEMUNLOCK, &mtdEraseInfo); 
    122         if (ioctl (fd, MEMERASE, &mtdEraseInfo) < 0) { 
    123                 fprintf(stderr, "Erasing mtd failed.\n"); 
    124                 exit(1); 
    125         } 
     123        if (ioctl (fd, MEMERASE, &mtdEraseInfo) < 0) 
     124                return -1; 
     125 
    126126        return 0; 
    127127} 
     
    147147static int mtd_check(const char *mtd) 
    148148{ 
     149        char *next = NULL; 
     150        char *str = NULL; 
    149151        int fd; 
    150152 
    151         fd = mtd_check_open(mtd); 
    152         if (!fd) 
    153                 return 0; 
    154  
    155         if (!buf) 
    156                 buf = malloc(erasesize); 
    157  
    158         close(fd); 
     153        if (strchr(mtd, ':')) { 
     154                str = strdup(mtd); 
     155                mtd = str; 
     156        } 
     157 
     158        do { 
     159                next = strchr(mtd, ':'); 
     160                if (next) { 
     161                        *next = 0; 
     162                        next++; 
     163                } 
     164 
     165                fd = mtd_check_open(mtd); 
     166                if (!fd) 
     167                        return 0; 
     168 
     169                if (!buf) 
     170                        buf = malloc(erasesize); 
     171 
     172                close(fd); 
     173                mtd = next; 
     174        } while (next); 
     175 
     176        if (str) 
     177                free(str); 
     178 
    159179        return 1; 
    160180} 
     
    163183mtd_unlock(const char *mtd) 
    164184{ 
     185        struct erase_info_user mtdLockInfo; 
     186        char *next = NULL; 
     187        char *str = NULL; 
    165188        int fd; 
    166         struct erase_info_user mtdLockInfo; 
     189 
     190        if (strchr(mtd, ':')) { 
     191                str = strdup(mtd); 
     192                mtd = str; 
     193        } 
     194 
     195        do { 
     196                next = strchr(mtd, ':'); 
     197                if (next) { 
     198                        *next = 0; 
     199                        next++; 
     200                } 
     201 
     202                fd = mtd_check_open(mtd); 
     203                if(fd <= 0) { 
     204                        fprintf(stderr, "Could not open mtd device: %s\n", mtd); 
     205                        exit(1); 
     206                } 
     207 
     208                if (quiet < 2) 
     209                        fprintf(stderr, "Unlocking %s ...\n", mtd); 
     210 
     211                mtdLockInfo.start = 0; 
     212                mtdLockInfo.length = mtdsize; 
     213                ioctl(fd, MEMUNLOCK, &mtdLockInfo); 
     214                close(fd); 
     215                mtd = next; 
     216        } while (next); 
     217 
     218        if (str) 
     219                free(str); 
     220 
     221        return 0; 
     222} 
     223 
     224static int 
     225mtd_erase(const char *mtd) 
     226{ 
     227        int fd; 
     228        struct erase_info_user mtdEraseInfo; 
     229 
     230        if (quiet < 2) 
     231                fprintf(stderr, "Erasing %s ...\n", mtd); 
    167232 
    168233        fd = mtd_check_open(mtd); 
     
    172237        } 
    173238 
    174         if (quiet < 2)  
    175                 fprintf(stderr, "Unlocking %s ...\n", mtd); 
    176  
    177         mtdLockInfo.start = 0; 
    178         mtdLockInfo.length = mtdsize; 
    179         if(ioctl(fd, MEMUNLOCK, &mtdLockInfo)) { 
    180                 close(fd); 
    181                 return 0; 
    182         } 
    183                  
     239        mtdEraseInfo.length = erasesize; 
     240 
     241        for (mtdEraseInfo.start = 0; 
     242                 mtdEraseInfo.start < mtdsize; 
     243                 mtdEraseInfo.start += erasesize) { 
     244 
     245                ioctl(fd, MEMUNLOCK, &mtdEraseInfo); 
     246                if(ioctl(fd, MEMERASE, &mtdEraseInfo)) 
     247                        fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start); 
     248        } 
     249 
    184250        close(fd); 
    185251        return 0; 
     252 
    186253} 
    187254 
    188255static int 
    189 mtd_erase(const char *mtd) 
     256mtd_refresh(const char *mtd) 
    190257{ 
    191258        int fd; 
    192         struct erase_info_user mtdEraseInfo; 
    193259 
    194260        if (quiet < 2) 
    195                 fprintf(stderr, "Erasing %s ...\n", mtd); 
     261                fprintf(stderr, "Refreshing mtd partition %s ... ", mtd); 
    196262 
    197263        fd = mtd_check_open(mtd); 
     
    201267        } 
    202268 
    203         mtdEraseInfo.length = erasesize; 
    204  
    205         for (mtdEraseInfo.start = 0; 
    206                  mtdEraseInfo.start < mtdsize; 
    207                  mtdEraseInfo.start += erasesize) { 
    208                  
    209                 ioctl(fd, MEMUNLOCK, &mtdEraseInfo); 
    210                 if(ioctl(fd, MEMERASE, &mtdEraseInfo)) 
    211                         fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start); 
    212         }                
    213  
    214         close(fd); 
    215         return 0; 
    216  
    217 } 
    218  
    219 static int 
    220 mtd_refresh(const char *mtd) 
    221 { 
    222         int fd; 
    223  
    224         if (quiet < 2) 
    225                 fprintf(stderr, "Refreshing mtd partition %s ... ", mtd); 
    226  
    227         fd = mtd_check_open(mtd); 
    228         if(fd <= 0) { 
    229                 fprintf(stderr, "Could not open mtd device: %s\n", mtd); 
    230                 exit(1); 
    231         } 
    232  
    233269        if (ioctl(fd, MTDREFRESH, NULL)) { 
    234270                fprintf(stderr, "Failed to refresh the MTD device\n"); 
     
    245281 
    246282static int 
    247 mtd_write(int imagefd, const char *mtd) 
    248 { 
     283mtd_write(int imagefd, const char *mtd, char *fis_layout) 
     284{ 
     285        char *next = NULL; 
     286        char *str = NULL; 
    249287        int fd, result; 
    250288        ssize_t r, w, e; 
     289        uint32_t offset = 0; 
     290 
     291#ifdef FIS_SUPPORT 
     292        static struct fis_part new_parts[MAX_ARGS]; 
     293        static struct fis_part old_parts[MAX_ARGS]; 
     294        int n_new = 0, n_old = 0; 
     295 
     296        if (fis_layout) { 
     297                const char *tmp = mtd; 
     298                char *word, *brkt; 
     299                int ret; 
     300 
     301                memset(&old_parts, 0, sizeof(old_parts)); 
     302                memset(&new_parts, 0, sizeof(new_parts)); 
     303 
     304                do { 
     305                        next = strchr(tmp, ':'); 
     306                        if (!next) 
     307                                next = (char *) tmp + strlen(tmp); 
     308 
     309                        memcpy(old_parts[n_old].name, tmp, next - tmp); 
     310 
     311                        n_old++; 
     312                        tmp = next + 1; 
     313                } while(*next); 
     314 
     315                for (word = strtok_r(fis_layout, ",", &brkt); 
     316                     word; 
     317                         word = strtok_r(NULL, ",", &brkt)) { 
     318 
     319                        tmp = strtok(word, ":"); 
     320                        strncpy((char *) new_parts[n_new].name, tmp, sizeof(new_parts[n_new].name) - 1); 
     321 
     322                        tmp = strtok(NULL, ":"); 
     323                        if (!tmp) 
     324                                goto next; 
     325 
     326                        new_parts[n_new].size = strtoul(tmp, NULL, 0); 
     327 
     328                        tmp = strtok(NULL, ":"); 
     329                        if (!tmp) 
     330                                goto next; 
     331 
     332                        new_parts[n_new].loadaddr = strtoul(tmp, NULL, 16); 
     333next: 
     334                        n_new++; 
     335                } 
     336                ret = fis_validate(old_parts, n_old, new_parts, n_new); 
     337                if (ret < 0) { 
     338                        fprintf(stderr, "Failed to validate the new FIS partition table\n"); 
     339                        exit(1); 
     340                } 
     341                if (ret == 0) 
     342                        fis_layout = NULL; 
     343        } 
     344#endif 
     345 
     346        if (strchr(mtd, ':')) { 
     347                str = strdup(mtd); 
     348                mtd = str; 
     349        } 
     350 
     351        r = 0; 
     352 
     353resume: 
     354        next = strchr(mtd, ':'); 
     355        if (next) { 
     356                *next = 0; 
     357                next++; 
     358        } 
    251359 
    252360        fd = mtd_check_open(mtd); 
     
    255363                exit(1); 
    256364        } 
    257                  
     365 
    258366        if (quiet < 2) 
    259367                fprintf(stderr, "Writing from %s to %s ... ", imagefile, mtd); 
    260368 
    261         r = w = e = 0; 
     369        w = e = 0; 
    262370        if (!quiet) 
    263371                fprintf(stderr, " [ ]"); 
    264372 
    265373        for (;;) { 
    266                 /* buffer may contain data already (from trx check) */ 
    267                 do { 
     374                /* buffer may contain data already (from trx check or last mtd partition write attempt) */ 
     375                while (buflen < erasesize) { 
    268376                        r = read(imagefd, buf + buflen, erasesize - buflen); 
    269377                        if (r < 0) { 
     
    280388 
    281389                        buflen += r; 
    282                 } while (buflen < erasesize); 
     390                } 
    283391 
    284392                if (buflen == 0) 
     
    305413                                fprintf(stderr, "\b\b\b[e]"); 
    306414 
    307                         mtd_erase_block(fd, e); 
     415 
     416                        if (mtd_erase_block(fd, e) < 0) { 
     417                                if (next) { 
     418                                        if (w < e) { 
     419                                                write(fd, buf + offset, e - w); 
     420                                                offset = e - w; 
     421                                        } 
     422                                        w = 0; 
     423                                        e = 0; 
     424                                        close(fd); 
     425                                        mtd = next; 
     426                                        fprintf(stderr, "\b\b\b   \n"); 
     427                                        goto resume; 
     428                                } else { 
     429                                        fprintf(stderr, "Failed to erase block\n"); 
     430                                        exit(1); 
     431                                } 
     432                        } 
    308433 
    309434                        /* erase the chunk */ 
    310435                        e += erasesize; 
    311436                } 
    312                  
     437 
    313438                if (!quiet) 
    314439                        fprintf(stderr, "\b\b\b[w]"); 
    315                  
    316                 if ((result = write(fd, buf, buflen)) < buflen) { 
     440 
     441                if ((result = write(fd, buf + offset, buflen)) < buflen) { 
    317442                        if (result < 0) { 
    318443                                fprintf(stderr, "Error writing image.\n"); 
     
    326451 
    327452                buflen = 0; 
    328         } 
     453                offset = 0; 
     454        } 
     455 
    329456        if (!quiet) 
    330                 fprintf(stderr, "\b\b\b\b"); 
     457                fprintf(stderr, "\b\b\b\b    "); 
    331458 
    332459done: 
     
    334461                fprintf(stderr, "\n"); 
    335462 
     463#ifdef FIS_SUPPORT 
     464        if (fis_layout) { 
     465                if (fis_remap(old_parts, n_old, new_parts, n_new) < 0) 
     466                        fprintf(stderr, "Failed to update the FIS partition table\n"); 
     467        } 
     468#endif 
     469 
    336470        close(fd); 
    337471        return 0; 
     
    340474static void usage(void) 
    341475{ 
    342         fprintf(stderr, "Usage: mtd [<options> ...] <command> [<arguments> ...] <device>\n\n" 
     476        fprintf(stderr, "Usage: mtd [<options> ...] <command> [<arguments> ...] <device>[:<device>...]\n\n" 
    343477        "The device is in the format of mtdX (eg: mtd4) or its label.\n" 
    344478        "mtd recognizes these commands:\n" 
     
    356490        "        -d <name>               directory for jffs2write, defaults to \"tmp\"\n" 
    357491        "        -j <name>               integrate <file> into jffs2 data when writing an image\n" 
     492#ifdef FIS_SUPPORT 
     493        "        -F <part>[:<size>[:<entrypoint>]][,<part>...]\n" 
     494        "                                alter the fis partition table to create new partitions replacing\n" 
     495        "                                the partitions provided as argument to the write command\n" 
     496        "                                (only valid together with the write command)\n" 
     497#endif 
    358498        "\n" 
    359499        "Example: To write linux.trx to mtd4 labeled as linux and reboot afterwards\n" 
     
    379519        int ch, i, boot, imagefd = 0, force, unlocked; 
    380520        char *erase[MAX_ARGS], *device = NULL; 
     521        char *fis_layout = NULL; 
    381522        enum { 
    382523                CMD_ERASE, 
     
    386527                CMD_JFFS2WRITE 
    387528        } cmd = -1; 
    388          
     529 
    389530        erase[0] = NULL; 
    390531        boot = 0; 
     
    393534        quiet = 0; 
    394535 
    395         while ((ch = getopt(argc, argv, "frqe:d:j:")) != -1) 
     536        while ((ch = getopt(argc, argv, 
     537#ifdef FIS_SUPPORT 
     538                        "F:" 
     539#endif 
     540                        "frqe:d:j:")) != -1) 
    396541                switch (ch) { 
    397542                        case 'f': 
     
    411556                                while ((erase[i] != NULL) && ((i + 1) < MAX_ARGS)) 
    412557                                        i++; 
    413                                          
     558 
    414559                                erase[i++] = optarg; 
    415560                                erase[i] = NULL; 
     
    418563                                jffs2dir = optarg; 
    419564                                break; 
     565#ifdef FIS_SUPPORT 
     566                        case 'F': 
     567                                fis_layout = optarg; 
     568                                break; 
     569#endif 
    420570                        case '?': 
    421571                        default: 
     
    424574        argc -= optind; 
    425575        argv += optind; 
    426          
     576 
    427577        if (argc < 2) 
    428578                usage(); 
     
    440590                cmd = CMD_WRITE; 
    441591                device = argv[2]; 
    442          
     592 
    443593                if (strcmp(argv[1], "-") == 0) { 
    444594                        imagefile = "<stdin>"; 
     
    451601                        } 
    452602                } 
    453          
     603 
    454604                if (!mtd_check(device)) { 
    455605                        fprintf(stderr, "Can't open device for writing!\n"); 
     
    464614                cmd = CMD_JFFS2WRITE; 
    465615                device = argv[2]; 
    466          
     616 
    467617                imagefile = argv[1]; 
    468618                if (!mtd_check(device)) { 
     
    475625 
    476626        sync(); 
    477          
     627 
    478628        i = 0; 
    479629        unlocked = 0; 
     
    485635                i++; 
    486636        } 
    487          
    488                  
     637 
    489638        switch (cmd) { 
    490639                case CMD_UNLOCK: 
     
    500649                        if (!unlocked) 
    501650                                mtd_unlock(device); 
    502                         mtd_write(imagefd, device); 
     651                        mtd_write(imagefd, device, fis_layout); 
    503652                        break; 
    504653                case CMD_JFFS2WRITE: 
     
    513662 
    514663        sync(); 
    515          
     664 
    516665        if (boot) 
    517666                do_reboot(); 
Note: See TracChangeset for help on using the changeset viewer.