2 * (C) Copyright 2003-2004
3 * Gary Jennejohn, DENX Software Engineering, garyj@denx.de.
4 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
6 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/byteorder.h>
18 #include "auto_update.h"
20 #ifdef CONFIG_AUTO_UPDATE
22 #if !defined(CONFIG_CMD_FAT)
23 #error "must define CONFIG_CMD_FAT"
26 extern au_image_t au_image[];
27 extern int N_AU_IMAGES;
29 /* where to load files into memory */
30 #define LOAD_ADDR ((unsigned char *)0x100000)
31 #define MAX_LOADSZ 0x1c00000
34 extern int fat_register_device(block_dev_desc_t *, int);
35 extern int file_fat_detectfs(void);
36 extern long file_fat_read(const char *, void *, unsigned long);
37 long do_fat_read (const char *filename, void *buffer,
38 unsigned long maxsize, int dols);
40 extern block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
42 int au_check_cksum_valid(int i, long nbytes)
46 hdr = (image_header_t *)LOAD_ADDR;
47 #if defined(CONFIG_FIT)
48 if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
49 puts ("Non legacy image format not supported\n");
54 if ((au_image[i].type == AU_FIRMWARE) &&
55 (au_image[i].size != image_get_data_size (hdr))) {
56 printf ("Image %s has wrong size\n", au_image[i].name);
60 if (nbytes != (image_get_image_size (hdr))) {
61 printf ("Image %s bad total SIZE\n", au_image[i].name);
65 /* check the data CRC */
66 if (!image_check_dcrc (hdr)) {
67 printf ("Image %s bad data checksum\n", au_image[i].name);
73 int au_check_header_valid(int i, long nbytes)
77 hdr = (image_header_t *)LOAD_ADDR;
78 #if defined(CONFIG_FIT)
79 if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
80 puts ("Non legacy image format not supported\n");
85 /* check the easy ones first */
86 if (nbytes < image_get_header_size ()) {
87 printf ("Image %s bad header SIZE\n", au_image[i].name);
90 if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) {
91 printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
94 if (!image_check_hcrc (hdr)) {
95 printf ("Image %s bad header checksum\n", au_image[i].name);
99 /* check the type - could do this all in one gigantic if() */
100 if (((au_image[i].type & AU_TYPEMASK) == AU_FIRMWARE) &&
101 !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
102 printf ("Image %s wrong type\n", au_image[i].name);
105 if (((au_image[i].type & AU_TYPEMASK) == AU_SCRIPT) &&
106 !image_check_type (hdr, IH_TYPE_SCRIPT)) {
107 printf ("Image %s wrong type\n", au_image[i].name);
114 int au_do_update(int i, long sz)
123 hdr = (image_header_t *)LOAD_ADDR;
124 #if defined(CONFIG_FIT)
125 if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
126 puts ("Non legacy image format not supported\n");
131 switch (au_image[i].type & AU_TYPEMASK) {
133 printf("Executing script %s\n", au_image[i].name);
135 /* execute a script */
136 if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
137 addr = (char *)((char *)hdr + image_get_header_size ());
138 /* stick a NULL at the end of the script, otherwise */
139 /* parse_string_outer() runs off the end. */
140 addr[image_get_data_size (hdr)] = 0;
144 * Replace cr/lf with ;
147 while (addr[k] != 0) {
148 if ((addr[k] == 10) || (addr[k] == 13)) {
154 run_command(addr, 0);
163 start = au_image[i].start;
164 end = au_image[i].start + au_image[i].size - 1;
167 * do not update firmware when image is already in flash.
169 if (au_image[i].type == AU_FIRMWARE) {
170 char *orig = (char*)start;
171 char *new = (char *)((char *)hdr +
172 image_get_header_size ());
173 nbytes = image_get_data_size (hdr);
176 if (*orig++ != *new++) {
181 printf ("Skipping firmware update - "
182 "images are identical\n");
187 /* unprotect the address range */
188 if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) ||
189 (au_image[i].type == AU_FIRMWARE)) {
190 flash_sect_protect (0, start, end);
194 * erase the address range.
196 if (au_image[i].type != AU_NAND) {
197 printf ("Updating NOR FLASH with image %s\n",
199 debug ("flash_sect_erase(%lx, %lx);\n", start, end);
200 flash_sect_erase (start, end);
205 /* strip the header - except for the kernel and ramdisk */
206 if (au_image[i].type != AU_FIRMWARE) {
208 off = image_get_header_size ();
209 nbytes = image_get_image_size (hdr);
211 addr = (char *)((char *)hdr + image_get_header_size ());
213 nbytes = image_get_data_size (hdr);
217 * copy the data from RAM to FLASH
219 if (au_image[i].type != AU_NAND) {
220 debug ("flash_write(%p, %lx, %x)\n",
221 addr, start, nbytes);
222 rc = flash_write ((char *)addr, start,
228 printf ("Flashing failed due to error %d\n", rc);
233 * check the dcrc of the copy
235 if (au_image[i].type != AU_NAND) {
236 rc = crc32 (0, (uchar *)(start + off),
237 image_get_data_size (hdr));
239 if (rc != image_get_dcrc (hdr)) {
240 printf ("Image %s Bad Data Checksum After COPY\n",
245 /* protect the address range */
246 /* this assumes that ONLY the firmware is protected! */
247 if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) ||
248 (au_image[i].type == AU_FIRMWARE)) {
249 flash_sect_protect (1, start, end);
255 printf("Wrong image type selected!\n");
261 static void process_macros (const char *input, char *output)
264 const char *varname_start = NULL;
265 int inputcnt = strlen (input);
266 int outputcnt = CONFIG_SYS_CBSIZE;
267 int state = 0; /* 0 = waiting for '$' */
268 /* 1 = waiting for '(' or '{' */
269 /* 2 = waiting for ')' or '}' */
270 /* 3 = waiting for ''' */
272 char *output_start = output;
274 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n",
275 strlen(input), input);
278 prev = '\0'; /* previous character */
280 while (inputcnt && outputcnt) {
285 /* remove one level of escape characters */
286 if ((c == '\\') && (prev != '\\')) {
295 case 0: /* Waiting for (unescaped) $ */
296 if ((c == '\'') && (prev != '\\')) {
300 if ((c == '$') && (prev != '\\')) {
307 case 1: /* Waiting for ( */
308 if (c == '(' || c == '{') {
310 varname_start = input;
322 case 2: /* Waiting for ) */
323 if (c == ')' || c == '}') {
325 char envname[CONFIG_SYS_CBSIZE], *envval;
326 /* Varname # of chars */
327 int envcnt = input - varname_start - 1;
329 /* Get the varname */
330 for (i = 0; i < envcnt; i++) {
331 envname[i] = varname_start[i];
336 envval = getenv (envname);
338 /* Copy into the line if it exists */
340 while ((*envval) && outputcnt) {
341 *(output++) = *(envval++);
344 /* Look for another '$' */
348 case 3: /* Waiting for ' */
349 if ((c == '\'') && (prev != '\\')) {
364 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
365 strlen (output_start), output_start);
370 * this is called from board_init() after the hardware has been set up
371 * and is usable. That seems like a good time to do this.
372 * Right now the return value is ignored.
374 int do_auto_update(void)
376 block_dev_desc_t *stor_dev = NULL;
378 int i, res, old_ctrlc;
383 if (ide_dev_desc[0].type != DEV_TYPE_UNKNOWN) {
384 stor_dev = get_dev ("ide", 0);
385 if (stor_dev == NULL) {
386 debug ("ide: unknown device\n");
391 if (fat_register_device (stor_dev, 1) != 0) {
392 debug ("Unable to register ide disk 0:1\n");
397 * Check if magic file is present
399 if ((n = do_fat_read (AU_MAGIC_FILE, buffer,
400 sizeof(buffer), LS_NO)) <= 0) {
401 debug ("No auto_update magic file (n=%d)\n", n);
405 #ifdef CONFIG_AUTO_UPDATE_SHOW
406 board_auto_update_show (1);
408 puts("\nAutoUpdate Disk detected! Trying to update system...\n");
410 /* make sure that we see CTRL-C and save the old state */
411 old_ctrlc = disable_ctrlc (0);
413 /* just loop thru all the possible files */
414 for (i = 0; i < N_AU_IMAGES; i++) {
416 * Try to expand the environment var in the fname
418 process_macros (au_image[i].name, str);
419 strcpy (au_image[i].name, str);
421 printf("Reading %s ...", au_image[i].name);
422 /* just read the header */
423 sz = do_fat_read (au_image[i].name, LOAD_ADDR,
424 image_get_header_size (), LS_NO);
425 debug ("read %s sz %ld hdr %d\n",
426 au_image[i].name, sz, image_get_header_size ());
427 if (sz <= 0 || sz < image_get_header_size ()) {
428 puts(" not found\n");
431 if (au_check_header_valid (i, sz) < 0) {
432 puts(" header not valid\n");
435 sz = do_fat_read (au_image[i].name, LOAD_ADDR,
437 debug ("read %s sz %ld hdr %d\n",
438 au_image[i].name, sz, image_get_header_size ());
439 if (sz <= 0 || sz <= image_get_header_size ()) {
440 puts(" not found\n");
443 if (au_check_cksum_valid (i, sz) < 0) {
444 puts(" checksum not valid\n");
450 res = au_do_update (i, sz);
451 /* let the user break out of the loop */
452 if (ctrlc() || had_ctrlc ()) {
459 /* restore the old state */
460 disable_ctrlc (old_ctrlc);
462 puts("AutoUpdate finished\n\n");
463 #ifdef CONFIG_AUTO_UPDATE_SHOW
464 board_auto_update_show (0);
470 int auto_update(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
477 autoupd, 1, 1, auto_update,
478 "Automatically update images",
481 #endif /* CONFIG_AUTO_UPDATE */