2 * (C) Copyright 2003-2004
3 * Gary Jennejohn, DENX Software Engineering, gj@denx.de.
4 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #include <asm/byteorder.h>
29 #include <linux/mtd/nand.h>
32 #include "auto_update.h"
34 #ifdef CONFIG_AUTO_UPDATE
36 #if !(CONFIG_COMMANDS & CFG_CMD_FAT)
37 #error "must define CFG_CMD_FAT"
40 extern au_image_t au_image
[];
41 extern int N_AU_IMAGES
;
48 #define debug(fmt,args...) printf (fmt ,##args)
50 #define debug(fmt,args...)
54 #define LOAD_ADDR ((unsigned char *)0x100000) /* where to load files into memory */
55 #define MAX_LOADSZ 0x1e00000
58 extern int fat_register_device(block_dev_desc_t
*, int);
59 extern int file_fat_detectfs(void);
60 extern long file_fat_read(const char *, void *, unsigned long);
61 long do_fat_read (const char *filename
, void *buffer
, unsigned long maxsize
, int dols
);
63 extern int trab_vfd (ulong
);
64 extern int transfer_pic(unsigned char, unsigned char *, int, int);
66 extern int flash_sect_erase(ulong
, ulong
);
67 extern int flash_sect_protect (int, ulong
, ulong
);
68 extern int flash_write (uchar
*, ulong
, ulong
);
69 /* change char* to void* to shutup the compiler */
70 extern block_dev_desc_t
*get_dev (char*, int);
72 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
73 /* references to names in cmd_nand.c */
74 #define NANDRW_READ 0x01
75 #define NANDRW_WRITE 0x00
76 #define NANDRW_JFFS2 0x02
77 #define NANDRW_JFFS2_SKIP 0x04
78 extern struct nand_chip nand_dev_desc
[];
79 extern int nand_rw(struct nand_chip
* nand
, int cmd
, size_t start
, size_t len
,
80 size_t * retlen
, u_char
* buf
);
81 extern int nand_erase(struct nand_chip
* nand
, size_t ofs
, size_t len
, int clean
);
82 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
84 extern block_dev_desc_t ide_dev_desc
[CFG_IDE_MAXDEVICE
];
87 int au_check_cksum_valid(int i
, long nbytes
)
90 unsigned long checksum
;
92 hdr
= (image_header_t
*)LOAD_ADDR
;
94 if ((au_image
[i
].type
== AU_FIRMWARE
) && (au_image
[i
].size
!= ntohl(hdr
->ih_size
))) {
95 printf ("Image %s has wrong size\n", au_image
[i
].name
);
99 if (nbytes
!= (sizeof(*hdr
) + ntohl(hdr
->ih_size
))) {
100 printf ("Image %s bad total SIZE\n", au_image
[i
].name
);
103 /* check the data CRC */
104 checksum
= ntohl(hdr
->ih_dcrc
);
106 if (crc32 (0, (uchar
*)(LOAD_ADDR
+ sizeof(*hdr
)), ntohl(hdr
->ih_size
))
108 printf ("Image %s bad data checksum\n", au_image
[i
].name
);
115 int au_check_header_valid(int i
, long nbytes
)
118 unsigned long checksum
;
120 hdr
= (image_header_t
*)LOAD_ADDR
;
121 /* check the easy ones first */
122 #undef CHECK_VALID_DEBUG
123 #ifdef CHECK_VALID_DEBUG
124 printf("magic %#x %#x ", ntohl(hdr
->ih_magic
), IH_MAGIC
);
125 printf("arch %#x %#x ", hdr
->ih_arch
, IH_CPU_PPC
);
126 printf("size %#x %#lx ", ntohl(hdr
->ih_size
), nbytes
);
127 printf("type %#x %#x ", hdr
->ih_type
, IH_TYPE_KERNEL
);
129 if (nbytes
< sizeof(*hdr
))
131 printf ("Image %s bad header SIZE\n", au_image
[i
].name
);
134 if (ntohl(hdr
->ih_magic
) != IH_MAGIC
|| hdr
->ih_arch
!= IH_CPU_PPC
)
136 printf ("Image %s bad MAGIC or ARCH\n", au_image
[i
].name
);
139 /* check the hdr CRC */
140 checksum
= ntohl(hdr
->ih_hcrc
);
143 if (crc32 (0, (uchar
*)hdr
, sizeof(*hdr
)) != checksum
) {
144 printf ("Image %s bad header checksum\n", au_image
[i
].name
);
147 hdr
->ih_hcrc
= htonl(checksum
);
149 /* check the type - could do this all in one gigantic if() */
150 if ((au_image
[i
].type
== AU_FIRMWARE
) && (hdr
->ih_type
!= IH_TYPE_FIRMWARE
)) {
151 printf ("Image %s wrong type\n", au_image
[i
].name
);
154 if ((au_image
[i
].type
== AU_SCRIPT
) && (hdr
->ih_type
!= IH_TYPE_SCRIPT
)) {
155 printf ("Image %s wrong type\n", au_image
[i
].name
);
159 /* recycle checksum */
160 checksum
= ntohl(hdr
->ih_size
);
162 #if 0 /* test-only */
163 /* for kernel and app the image header must also fit into flash */
165 checksum
+= sizeof(*hdr
);
166 /* check the size does not exceed space in flash. HUSH scripts */
167 /* all have ausize[] set to 0 */
168 if ((ausize
[idx
] != 0) && (ausize
[idx
] < checksum
)) {
169 printf ("Image %s is bigger than FLASH\n", au_image
[i
].name
);
178 int au_do_update(int i
, long sz
)
186 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
190 hdr
= (image_header_t
*)LOAD_ADDR
;
192 switch (au_image
[i
].type
) {
194 printf("Executing script %s\n", au_image
[i
].name
);
196 /* execute a script */
197 if (hdr
->ih_type
== IH_TYPE_SCRIPT
) {
198 addr
= (char *)((char *)hdr
+ sizeof(*hdr
));
199 /* stick a NULL at the end of the script, otherwise */
200 /* parse_string_outer() runs off the end. */
201 addr
[ntohl(hdr
->ih_size
)] = 0;
205 * Replace cr/lf with ;
208 while (addr
[k
] != 0) {
209 if ((addr
[k
] == 10) || (addr
[k
] == 13)) {
215 run_command(addr
, 0);
224 start
= au_image
[i
].start
;
225 end
= au_image
[i
].start
+ au_image
[i
].size
- 1;
228 * do not update firmware when image is already in flash.
230 if (au_image
[i
].type
== AU_FIRMWARE
) {
231 char *orig
= (char*)start
;
232 char *new = (char *)((char *)hdr
+ sizeof(*hdr
));
233 nbytes
= ntohl(hdr
->ih_size
);
236 if (*orig
++ != *new++) {
241 printf("Skipping firmware update - images are identical\n");
246 /* unprotect the address range */
247 /* this assumes that ONLY the firmware is protected! */
248 if (au_image
[i
].type
== AU_FIRMWARE
) {
249 flash_sect_protect(0, start
, end
);
253 * erase the address range.
255 if (au_image
[i
].type
!= AU_NAND
) {
256 printf("Updating NOR FLASH with image %s\n", au_image
[i
].name
);
257 debug ("flash_sect_erase(%lx, %lx);\n", start
, end
);
258 flash_sect_erase(start
, end
);
260 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
261 printf("Updating NAND FLASH with image %s\n", au_image
[i
].name
);
262 debug ("nand_erase(%lx, %lx);\n", start
, end
);
263 rc
= nand_erase (nand_dev_desc
, start
, end
- start
+ 1, 0);
264 debug ("nand_erase returned %x\n", rc
);
270 /* strip the header - except for the kernel and ramdisk */
271 if (au_image
[i
].type
!= AU_FIRMWARE
) {
274 nbytes
= sizeof(*hdr
) + ntohl(hdr
->ih_size
);
276 addr
= (char *)((char *)hdr
+ sizeof(*hdr
));
278 nbytes
= ntohl(hdr
->ih_size
);
282 * copy the data from RAM to FLASH
284 if (au_image
[i
].type
!= AU_NAND
) {
285 debug ("flash_write(%p, %lx %x)\n", addr
, start
, nbytes
);
286 rc
= flash_write((uchar
*)addr
, start
, nbytes
);
288 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
289 debug ("nand_rw(%p, %lx %x)\n", addr
, start
, nbytes
);
290 rc
= nand_rw(nand_dev_desc
, NANDRW_WRITE
| NANDRW_JFFS2
,
291 start
, nbytes
, (size_t *)&total
, (uchar
*)addr
);
292 debug ("nand_rw: ret=%x total=%d nbytes=%d\n", rc
, total
, nbytes
);
296 printf("Flashing failed due to error %d\n", rc
);
301 * check the dcrc of the copy
303 if (au_image
[i
].type
!= AU_NAND
) {
304 rc
= crc32 (0, (uchar
*)(start
+ off
), ntohl(hdr
->ih_size
));
306 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
307 rc
= nand_rw(nand_dev_desc
, NANDRW_READ
| NANDRW_JFFS2
| NANDRW_JFFS2_SKIP
,
308 start
, nbytes
, (size_t *)&total
, (uchar
*)addr
);
309 rc
= crc32 (0, (uchar
*)(addr
+ off
), ntohl(hdr
->ih_size
));
312 if (rc
!= ntohl(hdr
->ih_dcrc
)) {
313 printf ("Image %s Bad Data Checksum After COPY\n", au_image
[i
].name
);
317 /* protect the address range */
318 /* this assumes that ONLY the firmware is protected! */
319 if (au_image
[i
].type
== AU_FIRMWARE
) {
320 flash_sect_protect(1, start
, end
);
326 printf("Wrong image type selected!\n");
333 static void process_macros (const char *input
, char *output
)
336 const char *varname_start
= NULL
;
337 int inputcnt
= strlen (input
);
338 int outputcnt
= CFG_CBSIZE
;
339 int state
= 0; /* 0 = waiting for '$' */
340 /* 1 = waiting for '(' or '{' */
341 /* 2 = waiting for ')' or '}' */
342 /* 3 = waiting for ''' */
344 char *output_start
= output
;
346 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input
), input
);
349 prev
= '\0'; /* previous character */
351 while (inputcnt
&& outputcnt
) {
356 /* remove one level of escape characters */
357 if ((c
== '\\') && (prev
!= '\\')) {
366 case 0: /* Waiting for (unescaped) $ */
367 if ((c
== '\'') && (prev
!= '\\')) {
371 if ((c
== '$') && (prev
!= '\\')) {
378 case 1: /* Waiting for ( */
379 if (c
== '(' || c
== '{') {
381 varname_start
= input
;
393 case 2: /* Waiting for ) */
394 if (c
== ')' || c
== '}') {
396 char envname
[CFG_CBSIZE
], *envval
;
397 int envcnt
= input
-varname_start
-1; /* Varname # of chars */
399 /* Get the varname */
400 for (i
= 0; i
< envcnt
; i
++) {
401 envname
[i
] = varname_start
[i
];
406 envval
= getenv (envname
);
408 /* Copy into the line if it exists */
410 while ((*envval
) && outputcnt
) {
411 *(output
++) = *(envval
++);
414 /* Look for another '$' */
418 case 3: /* Waiting for ' */
419 if ((c
== '\'') && (prev
!= '\\')) {
434 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
435 strlen(output_start
), output_start
);
441 * this is called from board_init() after the hardware has been set up
442 * and is usable. That seems like a good time to do this.
443 * Right now the return value is ignored.
445 int do_auto_update(void)
447 block_dev_desc_t
*stor_dev
;
449 int i
, res
, cnt
, old_ctrlc
, got_ctrlc
;
454 * Check whether a CompactFlash is inserted
456 if (ide_dev_desc
[0].type
== DEV_TYPE_UNKNOWN
) {
457 return -1; /* no disk detected! */
460 /* check whether it has a partition table */
461 stor_dev
= get_dev("ide", 0);
462 if (stor_dev
== NULL
) {
463 debug ("Uknown device type\n");
466 if (fat_register_device(stor_dev
, 1) != 0) {
467 debug ("Unable to register ide disk 0:1 for fatls\n");
472 * Check if magic file is present
474 if (do_fat_read(AU_MAGIC_FILE
, buffer
, sizeof(buffer
), LS_NO
) <= 0) {
478 #ifdef CONFIG_AUTO_UPDATE_SHOW
479 board_auto_update_show(1);
481 puts("\nAutoUpdate Disk detected! Trying to update system...\n");
483 /* make sure that we see CTRL-C and save the old state */
484 old_ctrlc
= disable_ctrlc(0);
486 /* just loop thru all the possible files */
487 for (i
= 0; i
< N_AU_IMAGES
; i
++) {
489 * Try to expand the environment var in the fname
491 process_macros(au_image
[i
].name
, str
);
492 strcpy(au_image
[i
].name
, str
);
494 printf("Reading %s ...", au_image
[i
].name
);
495 /* just read the header */
496 sz
= do_fat_read(au_image
[i
].name
, LOAD_ADDR
, sizeof(image_header_t
), LS_NO
);
497 debug ("read %s sz %ld hdr %d\n",
498 au_image
[i
].name
, sz
, sizeof(image_header_t
));
499 if (sz
<= 0 || sz
< sizeof(image_header_t
)) {
500 puts(" not found\n");
503 if (au_check_header_valid(i
, sz
) < 0) {
504 puts(" header not valid\n");
507 sz
= do_fat_read(au_image
[i
].name
, LOAD_ADDR
, MAX_LOADSZ
, LS_NO
);
508 debug ("read %s sz %ld hdr %d\n",
509 au_image
[i
].name
, sz
, sizeof(image_header_t
));
510 if (sz
<= 0 || sz
<= sizeof(image_header_t
)) {
511 puts(" not found\n");
514 if (au_check_cksum_valid(i
, sz
) < 0) {
515 puts(" checksum not valid\n");
521 res
= au_do_update(i
, sz
);
522 /* let the user break out of the loop */
523 if (ctrlc() || had_ctrlc()) {
533 /* restore the old state */
534 disable_ctrlc(old_ctrlc
);
536 puts("AutoUpdate finished\n\n");
537 #ifdef CONFIG_AUTO_UPDATE_SHOW
538 board_auto_update_show(0);
545 int auto_update(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
552 autoupd
, 1, 1, auto_update
,
553 "autoupd - Automatically update images\n",
556 #endif /* CONFIG_AUTO_UPDATE */