Ticket #6008: stage02_image-creator.patch

File stage02_image-creator.patch, 6.6 KB (added by vx, 7 years ago)
  • tools/firmware-utils/src/zImage.c

     
     1/* 
     2 * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o. 
     3 * 
     4 * This program is free software; you can redistribute it and/or modify 
     5 * it under the terms of the GNU General Public License as published by 
     6 * the Free Software Foundation; either version 2 of the License, or 
     7 * (at your option) any later version. 
     8 * 
     9 * This program is distributed in the hope that it will be useful, 
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
     12 * General Public License for more details. 
     13 * 
     14 * You should have received a copy of the GNU General Public License 
     15 * along with this program; if not, write to the Free Software 
     16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
     17 */ 
     18 
     19 
     20#include <stdio.h> 
     21#include <stdlib.h> 
     22#include <stdint.h> 
     23#include <string.h> 
     24#include <endian.h> 
     25#include <byteswap.h> 
     26#include <unistd.h> 
     27 
     28 
     29#if __BYTE_ORDER == __BIG_ENDIAN 
     30#define STORE32_LE(a)   (a) 
     31#elif __BYTE_ORDER == __LITTLE_ENDIAN 
     32#define STORE32_LE(a)   bswap_32(a) 
     33#endif 
     34 
     35 
     36#define HEADER_MARK_START       0x12345678 
     37#define HEADER_MARK_END         0x87654321 
     38#define HEADER_TYPE_KERNEL      1 
     39 
     40 
     41enum board_type 
     42{ 
     43        BOARD_WLA5000AP = 0, 
     44        BOARD_RDAA81, 
     45}; 
     46 
     47struct firmware_type 
     48{ 
     49        enum board_type board; 
     50        char            *board_name; 
     51        char            *board_string; 
     52        uint32_t        max_length; 
     53}; 
     54 
     55 
     56#define BOARD(a,b,c,d) { .board = a, \ 
     57                         .board_name = b, \ 
     58                         .board_string = c, \ 
     59                         .max_length = d } 
     60 
     61struct firmware_type firmware_types[] = { 
     62 
     63        /* Ovislink WLA-5000AP v1/v2/v3 */ 
     64        BOARD(BOARD_WLA5000AP, "WLA-5000AP", "OVISCA401 Atheors 2312 11a/g Wireless EA", 0x3A0000 ), 
     65 
     66        /* WNC CA8-4 / RDAA-81 */ 
     67        BOARD(BOARD_RDAA81, "RDAA-81", "CA804.SOB Atheors 2312 11a/g Wireless AP", 0x3A0000 ), 
     68 
     69        BOARD(0, NULL, NULL, 0) 
     70}; 
     71 
     72struct img_header 
     73{ 
     74        uint32_t        head; 
     75        char            board_id[52]; 
     76        uint32_t        type; 
     77        uint32_t        img_length; 
     78        uint32_t        crc; 
     79        char            reserved[56]; 
     80        uint32_t        tail; 
     81}; 
     82 
     83 
     84long file_length(FILE *f) 
     85{ 
     86        long ret; 
     87 
     88        fseek(f, 0L, SEEK_END); 
     89        ret = ftell(f); 
     90        rewind(f); 
     91 
     92        return(ret); 
     93} 
     94 
     95 
     96void usage(void) 
     97{ 
     98        fprintf(stderr, "Usage: zImage -b board_type -o outfile -r rootfs -k kernel\n"); 
     99} 
     100 
     101 
     102int main(int argc, char **argv) 
     103{ 
     104        int opt_board = -1; 
     105        FILE *opt_kernel = NULL; 
     106        FILE *opt_rootfs = NULL; 
     107        FILE *opt_outfile = NULL; 
     108        int c; 
     109        int i; 
     110        struct firmware_type *fw_type; 
     111        int ret = EXIT_FAILURE; 
     112        struct img_header fw; 
     113        unsigned char *buf = NULL; 
     114        int fw_length = 0, kernel_length = 0, kernel_length_up = 0; 
     115        uint32_t fw_crc = 0; 
     116        size_t processed; 
     117 
     118        while ((c = getopt(argc, argv, "b:o:r:k:")) != -1) 
     119        { 
     120                switch (c) { 
     121                        case 'b': 
     122                                for (fw_type = firmware_types; fw_type->board_name; fw_type++) 
     123                                { 
     124                                        if(strcmp(fw_type->board_name, optarg) == 0) 
     125                                        { 
     126                                                opt_board = fw_type->board; 
     127                                                break; 
     128                                        } 
     129                                } 
     130                                if (opt_board == -1) 
     131                                { 
     132                                        fprintf(stderr, "Unknown board!\n\n"); 
     133                                        usage(); 
     134                                        goto err; 
     135                                } 
     136                                break; 
     137 
     138                        case 'k': 
     139                                if (! (opt_kernel = fopen(optarg, "r"))) 
     140                                { 
     141                                        fprintf(stderr, "Can't open \"%s\" for reading!\n\n", optarg); 
     142                                        usage(); 
     143                                        goto err; 
     144                                } 
     145                                break; 
     146 
     147                        case 'r': 
     148                                if (! (opt_rootfs = fopen(optarg, "r"))) 
     149                                { 
     150                                        fprintf(stderr, "Can't open \"%s\" for reading!\n\n", optarg); 
     151                                        usage(); 
     152                                        goto err; 
     153                                } 
     154                                break; 
     155 
     156                        case 'o': 
     157                                if (! (opt_outfile = fopen(optarg, "w"))) { 
     158                                        fprintf(stderr, "Can't open \"%s\" for writing!\n\n", optarg); 
     159                                        usage(); 
     160                                        goto err; 
     161                                } 
     162                                break; 
     163 
     164                        default: 
     165                                usage(); 
     166                } 
     167        } 
     168 
     169 
     170        if (opt_board == -1) 
     171        { 
     172                fprintf(stderr, "Board not specified!\n\n"); 
     173                usage(); 
     174                goto err; 
     175        } 
     176 
     177        if (! opt_rootfs) 
     178        { 
     179                fprintf(stderr, "Rootfs file not specified!\n\n"); 
     180                usage(); 
     181                goto err; 
     182        } 
     183 
     184        if (! opt_kernel) 
     185        { 
     186                fprintf(stderr, "Kernel file not specified!\n\n"); 
     187                usage(); 
     188                goto err; 
     189        } 
     190 
     191        if (! opt_outfile) 
     192        { 
     193                fprintf(stderr, "Outfile file not specified!\n\n"); 
     194                usage(); 
     195                goto err; 
     196        } 
     197 
     198 
     199        kernel_length_up = kernel_length = file_length(opt_kernel); 
     200        kernel_length_up -= kernel_length % 0x10000; 
     201        kernel_length_up += kernel_length_up < kernel_length ? 0x10000 : 0; 
     202        fw_length = kernel_length_up; 
     203 
     204        fw_length += file_length(opt_rootfs); 
     205 
     206        if (fw_length > fw_type->max_length) 
     207        { 
     208                fprintf(stderr, "Kernel + rootfs too big! (%d > %d)\n\n", 
     209                        fw_length, fw_type->max_length); 
     210                goto err; 
     211        } 
     212 
     213        fw.img_length = STORE32_LE(kernel_length);      // yes, kernel length! 
     214 
     215        fw.head = STORE32_LE(HEADER_MARK_START); 
     216        fw.tail = STORE32_LE(HEADER_MARK_END); 
     217        fw.type = STORE32_LE(HEADER_TYPE_KERNEL); 
     218 
     219        memset(fw.reserved, 0, sizeof(fw.reserved)); 
     220 
     221        memset(fw.board_id, 0, sizeof(fw.board_id)); 
     222        strcpy(fw.board_id, fw_type->board_string); 
     223 
     224 
     225        buf = (unsigned char*)malloc(fw_length); 
     226        if (! buf) 
     227        { 
     228                fprintf(stderr, "Can't allocate memory for image!\n\n"); 
     229                goto err; 
     230        } 
     231 
     232        /* kernel */ 
     233        processed = fread(buf, 1, kernel_length, opt_kernel); 
     234        if (processed != kernel_length) 
     235        { 
     236                fprintf(stderr, "Can't read whole kernel file!\n\n"); 
     237                goto err; 
     238        } 
     239 
     240        /* kernel crc */ 
     241        for (i=0; i<=kernel_length; i++) 
     242        { 
     243                fw_crc += (unsigned char)buf[i]; 
     244        } 
     245        fw.crc = STORE32_LE(fw_crc); 
     246 
     247 
     248        /* rootfs */ 
     249        processed = fread(buf + kernel_length_up, 1, fw_length - kernel_length_up, opt_rootfs); 
     250        if (processed != fw_length - kernel_length_up) 
     251        { 
     252                fprintf(stderr, "Can't read whole rootfs file!\n\n"); 
     253                goto err; 
     254        } 
     255 
     256 
     257        /* header to outfile */ 
     258        processed = fwrite(&fw, 1, sizeof(fw), opt_outfile); 
     259        if (processed != sizeof(fw)) 
     260        { 
     261                fprintf(stderr, "Can't write header to outfile!\n\n"); 
     262                goto err; 
     263        } 
     264 
     265        /* kernel + rootfs to outfile */ 
     266        processed = fwrite(buf, 1, fw_length, opt_outfile); 
     267        if (processed != fw_length) 
     268        { 
     269                fprintf(stderr, "Can't write kernel + rootfs to outfile!\n\n"); 
     270                goto err; 
     271        } 
     272 
     273        printf("Firmware successfully created!\n"); 
     274 
     275        ret = EXIT_SUCCESS; 
     276 
     277err: 
     278        if(opt_kernel) fclose(opt_kernel); 
     279        if(opt_rootfs) fclose(opt_rootfs); 
     280        if(opt_outfile) fclose(opt_outfile); 
     281        free(buf); 
     282 
     283        return(ret); 
     284} 
  • tools/firmware-utils/Makefile

     
    3232        $(call cc,mkfwimage,-lz) 
    3333        $(call cc,imagetag) 
    3434        $(call cc,add_header) 
     35        $(call cc,zImage) 
    3536endef 
    3637 
    3738define Build/Install