merge of '49118a4c6035353c0f8cf1aa30297dd36e43241f'
[vuplus_openembedded] / packages / neuros-pkggen / files / package.c
1 /*
2  * Copyright (C) 2006 - 2008 Neuros Technology LLC.
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; only support version 2 of the License.
7  *
8  *  This program is distributed in the hope that, in addition to its 
9  *  original purpose to support Neuros hardware, it will be useful 
10  *  otherwise, but WITHOUT ANY WARRANTY; without even the implied 
11  *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
12  *  See the GNU 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 /** package.c
20  *
21  *  This file for packaging some images to one package.
22  *  The package is named r3.upk.
23  *
24  *  02/22/2005          T.Qiu   
25  *                      Initial creation.
26  *  11/07/2007          T.Qiu
27  *                      change follow the new UPK structure
28  *  05/15/2008          JWU
29  *                      change for osd2.0
30  */
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include "package.h"
36
37 #define RETRYTIMES  15
38 #define VER_LIMIT_LEN   14
39 #define VER_HW2_LEN     4
40 #define SAFE_SIZE (250*1024*1024) //250MB
41
42 static package_header_t p_head;
43 static image_info_t     i_info[10];
44
45 static void print_image_info(image_info_t *iif)
46 {
47     printf("iif->i_type: %x\n",        iif->i_type);
48     printf("iif->i_imagesize: %d\n",   iif->i_imagesize);
49     printf("iif->i_startaddr_p: %d\n", iif->i_startaddr_p);
50     printf("iif->i_startaddr_f: %x\n", iif->i_startaddr_f);
51     printf("iif->i_endaddr_f: %x\n",   iif->i_endaddr_f);
52     printf("iif->i_name: %s\n",        iif->i_name);
53     printf("iif->i_version: %s\n",     iif->i_version);
54 }
55
56 static void print_head_info(void)
57 {
58     package_header_t *phd = &p_head;
59
60     printf("phd->p_headsize: %x\n", phd->p_headsize);
61     printf("phd->p_reserve: %x\n",  phd->p_reserve);
62     printf("phd->p_headcrc: %x\n",  phd->p_headcrc);
63     printf("phd->p_datasize: %d\n", phd->p_datasize);
64     printf("phd->p_datacrc: %x\n",  phd->p_datacrc);
65     printf("phd->p_name: %s\n",     phd->p_name);
66     printf("phd->p_vuboot: %s\n",   phd->p_vuboot);
67     printf("phd->p_vkernel: %s\n",  phd->p_vkernel);
68     printf("phd->p_vrootfs: %s\n",  phd->p_vrootfs);
69     printf("phd->p_imagenum: %x\n", phd->p_imagenum);
70 }
71
72 static void print_version_info(version_info *ver_t)
73 {
74     printf("ver_t->upk_desc: %s\n", ver_t->upk_desc);
75     printf("ver_t->pack_id: %s\n",  ver_t->pack_id);
76     printf("ver_t->os_ver : %s\n",  ver_t->os_ver);
77     printf("ver_t->app_ver: %s\n",  ver_t->app_ver);
78 }
79
80 static int pack_firmware(FILE *fp_w, uint32 offst, int num, char *name[])
81 {
82     FILE *fp_r;
83     int i, j;
84     uint32 curptr, extcrc;
85     char ch;
86     package_header_t *phd = &p_head;
87     image_info_t     *iif;
88
89     /* read version file */
90     if ((fp_r = fopen(UBOOT_VER_FILE, "rb")) == NULL)
91     {
92         printf("Can't open uboot version file: %s\n", UBOOT_VER_FILE);
93         return(-1);
94     }
95     j=0;
96     while (1)
97     {
98         if (feof(fp_r)) break;
99         if (j > VER_LIMIT_LEN+1)
100         {
101             printf("uboot version can't be longer than 14\n");
102             goto bail;
103         }
104         phd->p_vuboot[j] = fgetc(fp_r);
105         if ((phd->p_vuboot[j]==0x0d) || (phd->p_vuboot[j]==0x0a))
106             phd->p_vuboot[j] = '\0';
107         j++;
108     }
109     fclose(fp_r);
110
111     if ((fp_r = fopen(KERNEL_VER_FILE, "rb")) == NULL)
112     {
113         printf("Can't open kernel version file: %s\n", KERNEL_VER_FILE);
114         return(-1);
115     }
116     j=0;
117     while (1)
118     {
119         if (feof(fp_r)) break;
120         if (j > VER_LIMIT_LEN+1)
121         {
122             printf("kernel version can't be longer than 14\n");
123             goto bail;
124         }
125         phd->p_vkernel[j]=fgetc(fp_r);
126         if ((phd->p_vkernel[j]==0x0d) || (phd->p_vkernel[j]==0x0a))
127             phd->p_vkernel[j] = '\0';
128         j++; 
129     }
130     fclose(fp_r);
131
132     if ((fp_r = fopen(ROOTFS_VER_FILE, "rb")) == NULL)
133     {
134         printf("Can't open rootfs version file: %s\n", ROOTFS_VER_FILE);
135         return(-1);
136     }
137     j=0;
138     while (1)
139     {
140         if (feof(fp_r)) break;
141         if (j > VER_LIMIT_LEN+1)
142         {
143             printf("rootfs version can't be longer than 14\n");
144             goto bail;
145         }
146         phd->p_vrootfs[j] = fgetc(fp_r);
147         if ((phd->p_vrootfs[j]==0x0d) ||(phd->p_vrootfs[j]==0x0a))
148             phd->p_vrootfs[j] = '\0';
149         j++;
150     }
151     fclose(fp_r);
152
153     phd->p_imagenum = (uint8)num;
154     phd->p_headsize = sizeof(package_header_t) + phd->p_imagenum * sizeof(image_info_t);
155
156     /* Bit[3] use to indicate osd2.0 package */
157     phd->p_reserve = 0x08;
158
159     phd->p_datasize = 0;
160     phd->p_datacrc  = 0;
161     phd->p_headcrc  = 0;
162
163     curptr = phd->p_headsize + sizeof(version_info);
164
165     for (i=0; i < phd->p_imagenum; i++)
166     {
167         /* image info */
168         iif = &i_info[i];
169         if (strncmp(name[i], ROOTFS_FILE_NAME, strlen(ROOTFS_FILE_NAME)) == 0)
170         {
171             iif->i_type = IH_TYPE_ROOTFS;
172             strncpy((char *)iif->i_name, ROOTFS_FILE_NAME, NAMELEN-1);
173
174             if ((fp_r = fopen(ROOTFS_VER_FILE, "rb")) == NULL)
175             {
176                 printf("Can't open kernel version file: %s\n", ROOTFS_VER_FILE);
177                 break;
178             }
179             for (j = 0; j < sizeof(iif->i_version); j++)
180             {
181                 if (feof(fp_r)) break;
182                 iif->i_version[j] = fgetc(fp_r);
183                 if ((iif->i_version[j]==0x0d) || (iif->i_version[j]==0x0a))
184                     iif->i_version[j] = '\0';
185             }
186             fclose(fp_r);
187         }
188         else if (strncmp(name[i], KERNEL_FILE_NAME, strlen(KERNEL_FILE_NAME)) == 0)
189         {
190             iif->i_type = IH_TYPE_KERNEL;
191             strncpy((char *)iif->i_name, KERNEL_FILE_NAME, NAMELEN-1);
192
193             if ((fp_r = fopen(KERNEL_VER_FILE, "rb")) == NULL)
194             {
195                 printf("Can't open kernel version file: %s\n", KERNEL_VER_FILE);
196                 break;
197             }
198             for (j = 0; j < sizeof(iif->i_version); j++)
199             {
200                 if (feof(fp_r)) break;
201                 iif->i_version[j] = fgetc(fp_r);
202                 if ((iif->i_version[j]==0x0d) ||(iif->i_version[j]==0x0a))
203                     iif->i_version[j] = '\0';
204             }
205             fclose(fp_r);
206         }
207         else if (strncmp(name[i], UBOOT_FILE_NAME, strlen(UBOOT_FILE_NAME)) == 0)
208         {
209             iif->i_type = IH_TYPE_UBOOT;
210             strncpy((char *)iif->i_name, UBOOT_FILE_NAME, NAMELEN-1);
211
212             if ((fp_r = fopen(UBOOT_VER_FILE, "rb")) == NULL)
213             {
214                 printf("Can't open uboot version file: %s\n", UBOOT_VER_FILE);
215                 break;
216             }
217             for (j = 0; j < sizeof(iif->i_version); j++)
218             {
219                 if (feof(fp_r)) break;
220                 iif->i_version[j] = fgetc(fp_r);
221                 if ((iif->i_version[j]==0x0d)|| (iif->i_version[j]==0x0a))
222                     iif->i_version[j] = '\0';
223             }
224             fclose(fp_r);
225         }
226         else if (strncmp(name[i], SCRIPT_FILE_NAME, strlen(SCRIPT_FILE_NAME)) == 0)
227         {
228             iif->i_type = IH_TYPE_SCRIPT;
229             strncpy((char *)iif->i_name, SCRIPT_FILE_NAME, NAMELEN-1);
230         }
231
232         /* address in flash*/
233         switch (iif->i_type)
234         {
235         case IH_TYPE_ROOTFS:
236             iif->i_startaddr_f = ROOTFS_ADDR_START;
237             iif->i_endaddr_f   = ROOTFS_ADDR_END;
238             break;
239         case IH_TYPE_KERNEL:
240             iif->i_startaddr_f = KERNEL_ADDR_START;
241             iif->i_endaddr_f   = KERNEL_ADDR_END;
242             break;       
243         case IH_TYPE_UBOOT:
244             iif->i_startaddr_f = UBOOT_ADDR_START;
245             iif->i_endaddr_f   = UBOOT_ADDR_END;
246             break;
247         case IH_TYPE_SCRIPT:
248             break;
249         default:
250             printf("un-handle image type\n");
251             break;
252         }
253
254         /* write whole image to package and calculate the imagesize*/
255         iif->i_imagesize = 0;
256         /* images file */
257         if ((fp_r = fopen(name[i], "rb")) == NULL)
258         {
259             printf("can't open file: %s\n", name[i]);
260             break;
261         }
262
263         fseek(fp_w, offst+curptr,SEEK_SET);
264         extcrc = 0;
265         while (!feof(fp_r))
266         {
267             ch = fgetc(fp_r);
268             fputc(ch, fp_w);
269             phd->p_datacrc = crc32(phd->p_datacrc,(uint8 *)&ch, 1);
270             iif->i_imagesize ++;
271         }
272         fclose(fp_r);
273
274         iif->i_startaddr_p = curptr-sizeof(version_info);
275         curptr += iif->i_imagesize;
276         phd->p_datasize += iif->i_imagesize;
277
278         print_image_info(iif); /* print iff*/
279
280         /*write image info */
281         fseek(fp_w, offst+sizeof(version_info)+sizeof(package_header_t)+i*sizeof(image_info_t), SEEK_SET);
282         if (fwrite(iif, sizeof(image_info_t), 1, fp_w) != 1)
283         {
284             printf("can not write iif into package\n");
285             break;
286         }
287     }
288
289     /* write package head*/
290     phd->p_headcrc = crc32(phd->p_headcrc, (uint8 *)phd, sizeof(package_header_t));
291     phd->p_headcrc = crc32(phd->p_headcrc, (uint8 *)i_info, phd->p_imagenum*sizeof(image_info_t));
292
293     print_head_info();  /* print phd */
294
295     fseek(fp_w, offst+sizeof(version_info), SEEK_SET);
296     if (fwrite((uint8 *)phd, sizeof(package_header_t), 1, fp_w) != 1)
297     {
298         printf("can not write head into package");
299         return(-1);
300     }
301     return 0;
302
303     bail:
304     fclose(fp_r);
305
306     return -1;
307 }
308
309 static int pack_ver_info(FILE *fp_w, uint32 offset, char *desc)
310 {
311     version_info ver_t;
312     FILE *fp_r;
313     int i;
314
315     memset((char *)&ver_t, 0, sizeof(version_info));
316
317     if (strlen(desc) >= DESCLEN)
318     {
319         printf("The upk_desc is too long\n");
320         return(-1);
321     }
322     strncpy((char *)ver_t.upk_desc, desc, DESCLEN-1);
323     strncpy((char *)ver_t.pack_id, (char *)PACKAGE_ID, NAMELEN-1);
324     strncpy((char *)ver_t.os_ver,  "0.00", VERLEN-1);
325     strncpy((char *)ver_t.app_ver, "0.00", VERLEN-1);
326
327     if ((fp_r = fopen(KERNEL_VER_FILE, "rb")) == NULL)
328     {
329         printf("Can't open OS version file: %s\n", KERNEL_VER_FILE);
330         return(-1);
331     }
332     for (i = 0; i < sizeof(ver_t.os_ver); i++)
333     {
334         if (feof(fp_r)) break;
335         ver_t.os_ver[i] = fgetc(fp_r);
336         if ((ver_t.os_ver[i]==0x0d) || (ver_t.os_ver[i]==0x0a))
337             ver_t.os_ver[i] = '\0';
338     }
339     fclose(fp_r);
340
341     if ((fp_r = fopen(ROOTFS_VER_FILE, "rb")) == NULL)
342     {
343         printf("Can't open App version file: %s\n", ROOTFS_VER_FILE);
344         return(-1);
345     }
346     for (i = 0; i < sizeof(ver_t.app_ver); i++)
347     {
348         if (feof(fp_r)) break;
349         ver_t.app_ver[i] = fgetc(fp_r);
350         if ((ver_t.app_ver[i]==0x0d) || (ver_t.app_ver[i]==0x0a))
351             ver_t.app_ver[i] = '\0';
352     }
353     fclose(fp_r);
354
355     fseek(fp_w, 0, SEEK_SET);
356     if (fwrite((uint8 *)&ver_t, sizeof(version_info), 1, fp_w) != 1)
357     {
358         printf("can not write the version struct into package\n");
359         return(-1);
360     }
361
362     print_version_info(&ver_t);
363
364     return(0);
365 }
366
367 /* argv[1] packet name
368     argv[2] upk descpription
369     argv[3] u-env image
370     argv[4] u-boot image
371     argv[5] kernel image
372     argv[5] rootfs image*/
373 int main(int argc, char *argv[])
374 {
375     FILE *fp_w;
376     uint32 hw_len = 0;
377     package_header_t *phd = &p_head;
378     struct stat buf;
379
380     printf("\npackage tool version %s \n", VERSION);
381
382     strncpy((char *)phd->p_name, argv[1], NAMELEN-1);
383     if ((fp_w = fopen((char *)phd->p_name, "wb+")) == NULL)
384     {
385         printf("Can't open %s\n",phd->p_name);
386         return(-1);
387     }
388
389     /* packet firmware to package */
390     if (pack_firmware(fp_w, hw_len, 4, &argv[3]) != 0)
391         return(-1);
392     /* packet upk_desc and version info */
393     if (pack_ver_info(fp_w, hw_len+phd->p_headsize, argv[2]) != 0)
394         return(-1);
395
396     fclose(fp_w);
397
398     stat((char *)phd->p_name, &buf);
399     if (buf.st_size > SAFE_SIZE)
400     {
401         printf("Warning!!!!! The upk size is larger than the safe size\n");
402     }
403
404     return 0;
405 }
406
407