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,
29 #include <asm/byteorder.h>
30 #if defined(CFG_NAND_LEGACY)
31 #include <linux/mtd/nand_legacy.h>
36 #include "auto_update.h"
38 #ifdef CONFIG_AUTO_UPDATE
40 #if !defined(CONFIG_CMD_FAT)
41 #error "must define CONFIG_CMD_FAT"
44 extern au_image_t au_image
[];
45 extern int N_AU_IMAGES
;
52 #define debug(fmt,args...) printf (fmt ,##args)
54 #define debug(fmt,args...)
58 #define LOAD_ADDR ((unsigned char *)0x100000) /* where to load files into memory */
59 #define MAX_LOADSZ 0x1e00000
62 extern int fat_register_device(block_dev_desc_t
*, int);
63 extern int file_fat_detectfs(void);
64 extern long file_fat_read(const char *, void *, unsigned long);
65 long do_fat_read (const char *filename
, void *buffer
, unsigned long maxsize
, int dols
);
67 extern int trab_vfd (ulong
);
68 extern int transfer_pic(unsigned char, unsigned char *, int, int);
70 extern int flash_sect_erase(ulong
, ulong
);
71 extern int flash_sect_protect (int, ulong
, ulong
);
72 extern int flash_write (char *, ulong
, ulong
);
74 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
75 /* references to names in cmd_nand.c */
76 #define NANDRW_READ 0x01
77 #define NANDRW_WRITE 0x00
78 #define NANDRW_JFFS2 0x02
79 #define NANDRW_JFFS2_SKIP 0x04
80 extern struct nand_chip nand_dev_desc
[];
81 extern int nand_legacy_rw(struct nand_chip
* nand
, int cmd
, size_t start
, size_t len
,
82 size_t * retlen
, u_char
* buf
);
83 extern int nand_legacy_erase(struct nand_chip
* nand
, size_t ofs
, size_t len
, int clean
);
86 extern block_dev_desc_t ide_dev_desc
[CFG_IDE_MAXDEVICE
];
89 int au_check_cksum_valid(int i
, long nbytes
)
93 hdr
= (image_header_t
*)LOAD_ADDR
;
95 if ((au_image
[i
].type
== AU_FIRMWARE
) &&
96 (au_image
[i
].size
!= image_get_data_size (hdr
))) {
97 printf ("Image %s has wrong size\n", au_image
[i
].name
);
101 if (nbytes
!= (image_get_image_size (hdr
))) {
102 printf ("Image %s bad total SIZE\n", au_image
[i
].name
);
106 /* check the data CRC */
107 if (!image_check_dcrc (hdr
)) {
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 ", image_get_magic (hdr
), IH_MAGIC
);
125 printf("arch %#x %#x ", image_get_arch (hdr
), IH_ARCH_PPC
);
126 printf("size %#x %#lx ", image_get_data_size (hdr
), nbytes
);
127 printf("type %#x %#x ", image_get_type (hdr
), IH_TYPE_KERNEL
);
129 if (nbytes
< image_get_header_size ())
131 printf ("Image %s bad header SIZE\n", au_image
[i
].name
);
134 if (!image_check_magic (hdr
) || !image_check_arch (hdr
, IH_ARCH_PPC
))
136 printf ("Image %s bad MAGIC or ARCH\n", au_image
[i
].name
);
139 if (!image_check_hcrc (hdr
)) {
140 printf ("Image %s bad header checksum\n", au_image
[i
].name
);
144 /* check the type - could do this all in one gigantic if() */
145 if ((au_image
[i
].type
== AU_FIRMWARE
) && !image_check_type (hdr
, IH_TYPE_FIRMWARE
)) {
146 printf ("Image %s wrong type\n", au_image
[i
].name
);
149 if ((au_image
[i
].type
== AU_SCRIPT
) && !image_check_type (hdr
, IH_TYPE_SCRIPT
)) {
150 printf ("Image %s wrong type\n", au_image
[i
].name
);
154 /* recycle checksum */
155 checksum
= image_get_data_size (hdr
);
157 #if 0 /* test-only */
158 /* for kernel and app the image header must also fit into flash */
160 checksum
+= image_get_header_size ();
161 /* check the size does not exceed space in flash. HUSH scripts */
162 /* all have ausize[] set to 0 */
163 if ((ausize
[idx
] != 0) && (ausize
[idx
] < checksum
)) {
164 printf ("Image %s is bigger than FLASH\n", au_image
[i
].name
);
173 int au_do_update(int i
, long sz
)
181 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
185 hdr
= (image_header_t
*)LOAD_ADDR
;
187 switch (au_image
[i
].type
) {
189 printf("Executing script %s\n", au_image
[i
].name
);
191 /* execute a script */
192 if (image_check_type (hdr
, IH_TYPE_SCRIPT
)) {
193 addr
= (char *)((char *)hdr
+ image_get_header_size ());
194 /* stick a NULL at the end of the script, otherwise */
195 /* parse_string_outer() runs off the end. */
196 addr
[image_get_data_size (hdr
)] = 0;
200 * Replace cr/lf with ;
203 while (addr
[k
] != 0) {
204 if ((addr
[k
] == 10) || (addr
[k
] == 13)) {
210 run_command(addr
, 0);
219 start
= au_image
[i
].start
;
220 end
= au_image
[i
].start
+ au_image
[i
].size
- 1;
223 * do not update firmware when image is already in flash.
225 if (au_image
[i
].type
== AU_FIRMWARE
) {
226 char *orig
= (char*)start
;
227 char *new = (char *)((char *)hdr
+ image_get_header_size ());
228 nbytes
= image_get_data_size (hdr
);
231 if (*orig
++ != *new++) {
236 printf("Skipping firmware update - images are identical\n");
241 /* unprotect the address range */
242 /* this assumes that ONLY the firmware is protected! */
243 if (au_image
[i
].type
== AU_FIRMWARE
) {
244 flash_sect_protect(0, start
, end
);
248 * erase the address range.
250 if (au_image
[i
].type
!= AU_NAND
) {
251 printf("Updating NOR FLASH with image %s\n", au_image
[i
].name
);
252 debug ("flash_sect_erase(%lx, %lx);\n", start
, end
);
253 flash_sect_erase(start
, end
);
255 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
256 printf("Updating NAND FLASH with image %s\n", au_image
[i
].name
);
257 debug ("nand_legacy_erase(%lx, %lx);\n", start
, end
);
258 rc
= nand_legacy_erase (nand_dev_desc
, start
, end
- start
+ 1, 0);
259 debug ("nand_legacy_erase returned %x\n", rc
);
265 /* strip the header - except for the kernel and ramdisk */
266 if (au_image
[i
].type
!= AU_FIRMWARE
) {
268 off
= image_get_header_size ();
269 nbytes
= image_get_image_size (hdr
);
271 addr
= (char *)((char *)hdr
+ image_get_header_size ());
273 nbytes
= image_get_data_size (hdr
);
277 * copy the data from RAM to FLASH
279 if (au_image
[i
].type
!= AU_NAND
) {
280 debug ("flash_write(%p, %lx %x)\n", addr
, start
, nbytes
);
281 rc
= flash_write((char *)addr
, start
, nbytes
);
283 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
284 debug ("nand_legacy_rw(%p, %lx %x)\n", addr
, start
, nbytes
);
285 rc
= nand_legacy_rw(nand_dev_desc
, NANDRW_WRITE
| NANDRW_JFFS2
,
286 start
, nbytes
, (size_t *)&total
, (uchar
*)addr
);
287 debug ("nand_legacy_rw: ret=%x total=%d nbytes=%d\n", rc
, total
, nbytes
);
293 printf("Flashing failed due to error %d\n", rc
);
298 * check the dcrc of the copy
300 if (au_image
[i
].type
!= AU_NAND
) {
301 rc
= crc32 (0, (uchar
*)(start
+ off
), image_get_data_size (hdr
));
303 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
304 rc
= nand_legacy_rw(nand_dev_desc
, NANDRW_READ
| NANDRW_JFFS2
| NANDRW_JFFS2_SKIP
,
305 start
, nbytes
, (size_t *)&total
, (uchar
*)addr
);
306 rc
= crc32 (0, (uchar
*)(addr
+ off
), image_get_data_size (hdr
));
309 if (rc
!= image_get_dcrc (hdr
)) {
310 printf ("Image %s Bad Data Checksum After COPY\n", au_image
[i
].name
);
314 /* protect the address range */
315 /* this assumes that ONLY the firmware is protected! */
316 if (au_image
[i
].type
== AU_FIRMWARE
) {
317 flash_sect_protect(1, start
, end
);
323 printf("Wrong image type selected!\n");
330 static void process_macros (const char *input
, char *output
)
333 const char *varname_start
= NULL
;
334 int inputcnt
= strlen (input
);
335 int outputcnt
= CFG_CBSIZE
;
336 int state
= 0; /* 0 = waiting for '$' */
337 /* 1 = waiting for '(' or '{' */
338 /* 2 = waiting for ')' or '}' */
339 /* 3 = waiting for ''' */
341 char *output_start
= output
;
343 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input
), input
);
346 prev
= '\0'; /* previous character */
348 while (inputcnt
&& outputcnt
) {
353 /* remove one level of escape characters */
354 if ((c
== '\\') && (prev
!= '\\')) {
363 case 0: /* Waiting for (unescaped) $ */
364 if ((c
== '\'') && (prev
!= '\\')) {
368 if ((c
== '$') && (prev
!= '\\')) {
375 case 1: /* Waiting for ( */
376 if (c
== '(' || c
== '{') {
378 varname_start
= input
;
390 case 2: /* Waiting for ) */
391 if (c
== ')' || c
== '}') {
393 char envname
[CFG_CBSIZE
], *envval
;
394 int envcnt
= input
-varname_start
-1; /* Varname # of chars */
396 /* Get the varname */
397 for (i
= 0; i
< envcnt
; i
++) {
398 envname
[i
] = varname_start
[i
];
403 envval
= getenv (envname
);
405 /* Copy into the line if it exists */
407 while ((*envval
) && outputcnt
) {
408 *(output
++) = *(envval
++);
411 /* Look for another '$' */
415 case 3: /* Waiting for ' */
416 if ((c
== '\'') && (prev
!= '\\')) {
431 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
432 strlen(output_start
), output_start
);
438 * this is called from board_init() after the hardware has been set up
439 * and is usable. That seems like a good time to do this.
440 * Right now the return value is ignored.
442 int do_auto_update(void)
444 block_dev_desc_t
*stor_dev
;
446 int i
, res
, cnt
, old_ctrlc
, got_ctrlc
;
451 * Check whether a CompactFlash is inserted
453 if (ide_dev_desc
[0].type
== DEV_TYPE_UNKNOWN
) {
454 return -1; /* no disk detected! */
457 /* check whether it has a partition table */
458 stor_dev
= get_dev("ide", 0);
459 if (stor_dev
== NULL
) {
460 debug ("Uknown device type\n");
463 if (fat_register_device(stor_dev
, 1) != 0) {
464 debug ("Unable to register ide disk 0:1 for fatls\n");
469 * Check if magic file is present
471 if (do_fat_read(AU_MAGIC_FILE
, buffer
, sizeof(buffer
), LS_NO
) <= 0) {
475 #ifdef CONFIG_AUTO_UPDATE_SHOW
476 board_auto_update_show(1);
478 puts("\nAutoUpdate Disk detected! Trying to update system...\n");
480 /* make sure that we see CTRL-C and save the old state */
481 old_ctrlc
= disable_ctrlc(0);
483 /* just loop thru all the possible files */
484 for (i
= 0; i
< N_AU_IMAGES
; i
++) {
486 * Try to expand the environment var in the fname
488 process_macros(au_image
[i
].name
, str
);
489 strcpy(au_image
[i
].name
, str
);
491 printf("Reading %s ...", au_image
[i
].name
);
492 /* just read the header */
493 sz
= do_fat_read(au_image
[i
].name
, LOAD_ADDR
, image_get_header_size (), LS_NO
);
494 debug ("read %s sz %ld hdr %d\n",
495 au_image
[i
].name
, sz
, image_get_header_size ());
496 if (sz
<= 0 || sz
< image_get_header_size ()) {
497 puts(" not found\n");
500 if (au_check_header_valid(i
, sz
) < 0) {
501 puts(" header not valid\n");
504 sz
= do_fat_read(au_image
[i
].name
, LOAD_ADDR
, MAX_LOADSZ
, LS_NO
);
505 debug ("read %s sz %ld hdr %d\n",
506 au_image
[i
].name
, sz
, image_get_header_size ());
507 if (sz
<= 0 || sz
<= image_get_header_size ()) {
508 puts(" not found\n");
511 if (au_check_cksum_valid(i
, sz
) < 0) {
512 puts(" checksum not valid\n");
518 res
= au_do_update(i
, sz
);
519 /* let the user break out of the loop */
520 if (ctrlc() || had_ctrlc()) {
530 /* restore the old state */
531 disable_ctrlc(old_ctrlc
);
533 puts("AutoUpdate finished\n\n");
534 #ifdef CONFIG_AUTO_UPDATE_SHOW
535 board_auto_update_show(0);
542 int auto_update(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
549 autoupd
, 1, 1, auto_update
,
550 "autoupd - Automatically update images\n",
553 #endif /* CONFIG_AUTO_UPDATE */