auto_update.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  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
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  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.
  13. *
  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.
  18. *
  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,
  22. * MA 02111-1307 USA
  23. */
  24. #include <common.h>
  25. #include <command.h>
  26. #include <image.h>
  27. #include <asm/byteorder.h>
  28. #include <fat.h>
  29. #include <part.h>
  30. #include "auto_update.h"
  31. #ifdef CONFIG_AUTO_UPDATE
  32. #if !defined(CONFIG_CMD_FAT)
  33. #error "must define CONFIG_CMD_FAT"
  34. #endif
  35. extern au_image_t au_image[];
  36. extern int N_AU_IMAGES;
  37. /* where to load files into memory */
  38. #define LOAD_ADDR ((unsigned char *)0x100000)
  39. #define MAX_LOADSZ 0x1c00000
  40. /* externals */
  41. extern int fat_register_device(block_dev_desc_t *, int);
  42. extern int file_fat_detectfs(void);
  43. extern long file_fat_read(const char *, void *, unsigned long);
  44. long do_fat_read (const char *filename, void *buffer,
  45. unsigned long maxsize, int dols);
  46. extern int flash_sect_erase(ulong, ulong);
  47. extern int flash_sect_protect (int, ulong, ulong);
  48. extern int flash_write (char *, ulong, ulong);
  49. extern block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
  50. int au_check_cksum_valid(int i, long nbytes)
  51. {
  52. image_header_t *hdr;
  53. hdr = (image_header_t *)LOAD_ADDR;
  54. #if defined(CONFIG_FIT)
  55. if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
  56. puts ("Non legacy image format not supported\n");
  57. return -1;
  58. }
  59. #endif
  60. if ((au_image[i].type == AU_FIRMWARE) &&
  61. (au_image[i].size != image_get_data_size (hdr))) {
  62. printf ("Image %s has wrong size\n", au_image[i].name);
  63. return -1;
  64. }
  65. if (nbytes != (image_get_image_size (hdr))) {
  66. printf ("Image %s bad total SIZE\n", au_image[i].name);
  67. return -1;
  68. }
  69. /* check the data CRC */
  70. if (!image_check_dcrc (hdr)) {
  71. printf ("Image %s bad data checksum\n", au_image[i].name);
  72. return -1;
  73. }
  74. return 0;
  75. }
  76. int au_check_header_valid(int i, long nbytes)
  77. {
  78. image_header_t *hdr;
  79. hdr = (image_header_t *)LOAD_ADDR;
  80. #if defined(CONFIG_FIT)
  81. if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
  82. puts ("Non legacy image format not supported\n");
  83. return -1;
  84. }
  85. #endif
  86. /* check the easy ones first */
  87. if (nbytes < image_get_header_size ()) {
  88. printf ("Image %s bad header SIZE\n", au_image[i].name);
  89. return -1;
  90. }
  91. if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) {
  92. printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
  93. return -1;
  94. }
  95. if (!image_check_hcrc (hdr)) {
  96. printf ("Image %s bad header checksum\n", au_image[i].name);
  97. return -1;
  98. }
  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);
  103. return -1;
  104. }
  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);
  108. return -1;
  109. }
  110. return 0;
  111. }
  112. int au_do_update(int i, long sz)
  113. {
  114. image_header_t *hdr;
  115. char *addr;
  116. long start, end;
  117. int off, rc;
  118. uint nbytes;
  119. int k;
  120. hdr = (image_header_t *)LOAD_ADDR;
  121. #if defined(CONFIG_FIT)
  122. if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
  123. puts ("Non legacy image format not supported\n");
  124. return -1;
  125. }
  126. #endif
  127. switch (au_image[i].type & AU_TYPEMASK) {
  128. case AU_SCRIPT:
  129. printf("Executing script %s\n", au_image[i].name);
  130. /* execute a script */
  131. if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
  132. addr = (char *)((char *)hdr + image_get_header_size ());
  133. /* stick a NULL at the end of the script, otherwise */
  134. /* parse_string_outer() runs off the end. */
  135. addr[image_get_data_size (hdr)] = 0;
  136. addr += 8;
  137. /*
  138. * Replace cr/lf with ;
  139. */
  140. k = 0;
  141. while (addr[k] != 0) {
  142. if ((addr[k] == 10) || (addr[k] == 13)) {
  143. addr[k] = ';';
  144. }
  145. k++;
  146. }
  147. run_command(addr, 0);
  148. return 0;
  149. }
  150. break;
  151. case AU_FIRMWARE:
  152. case AU_NOR:
  153. case AU_NAND:
  154. start = au_image[i].start;
  155. end = au_image[i].start + au_image[i].size - 1;
  156. /*
  157. * do not update firmware when image is already in flash.
  158. */
  159. if (au_image[i].type == AU_FIRMWARE) {
  160. char *orig = (char*)start;
  161. char *new = (char *)((char *)hdr +
  162. image_get_header_size ());
  163. nbytes = image_get_data_size (hdr);
  164. while (--nbytes) {
  165. if (*orig++ != *new++) {
  166. break;
  167. }
  168. }
  169. if (!nbytes) {
  170. printf ("Skipping firmware update - "
  171. "images are identical\n");
  172. break;
  173. }
  174. }
  175. /* unprotect the address range */
  176. if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) ||
  177. (au_image[i].type == AU_FIRMWARE)) {
  178. flash_sect_protect (0, start, end);
  179. }
  180. /*
  181. * erase the address range.
  182. */
  183. if (au_image[i].type != AU_NAND) {
  184. printf ("Updating NOR FLASH with image %s\n",
  185. au_image[i].name);
  186. debug ("flash_sect_erase(%lx, %lx);\n", start, end);
  187. flash_sect_erase (start, end);
  188. }
  189. udelay(10000);
  190. /* strip the header - except for the kernel and ramdisk */
  191. if (au_image[i].type != AU_FIRMWARE) {
  192. addr = (char *)hdr;
  193. off = image_get_header_size ();
  194. nbytes = image_get_image_size (hdr);
  195. } else {
  196. addr = (char *)((char *)hdr + image_get_header_size ());
  197. off = 0;
  198. nbytes = image_get_data_size (hdr);
  199. }
  200. /*
  201. * copy the data from RAM to FLASH
  202. */
  203. if (au_image[i].type != AU_NAND) {
  204. debug ("flash_write(%p, %lx, %x)\n",
  205. addr, start, nbytes);
  206. rc = flash_write ((char *)addr, start,
  207. (nbytes + 1) & ~1);
  208. } else {
  209. rc = -1;
  210. }
  211. if (rc != 0) {
  212. printf ("Flashing failed due to error %d\n", rc);
  213. return -1;
  214. }
  215. /*
  216. * check the dcrc of the copy
  217. */
  218. if (au_image[i].type != AU_NAND) {
  219. rc = crc32 (0, (uchar *)(start + off),
  220. image_get_data_size (hdr));
  221. }
  222. if (rc != image_get_dcrc (hdr)) {
  223. printf ("Image %s Bad Data Checksum After COPY\n",
  224. au_image[i].name);
  225. return -1;
  226. }
  227. /* protect the address range */
  228. /* this assumes that ONLY the firmware is protected! */
  229. if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) ||
  230. (au_image[i].type == AU_FIRMWARE)) {
  231. flash_sect_protect (1, start, end);
  232. }
  233. break;
  234. default:
  235. printf("Wrong image type selected!\n");
  236. }
  237. return 0;
  238. }
  239. static void process_macros (const char *input, char *output)
  240. {
  241. char c, prev;
  242. const char *varname_start = NULL;
  243. int inputcnt = strlen (input);
  244. int outputcnt = CONFIG_SYS_CBSIZE;
  245. int state = 0; /* 0 = waiting for '$' */
  246. /* 1 = waiting for '(' or '{' */
  247. /* 2 = waiting for ')' or '}' */
  248. /* 3 = waiting for ''' */
  249. #ifdef DEBUG_PARSER
  250. char *output_start = output;
  251. printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n",
  252. strlen(input), input);
  253. #endif
  254. prev = '\0'; /* previous character */
  255. while (inputcnt && outputcnt) {
  256. c = *input++;
  257. inputcnt--;
  258. if (state != 3) {
  259. /* remove one level of escape characters */
  260. if ((c == '\\') && (prev != '\\')) {
  261. if (inputcnt-- == 0)
  262. break;
  263. prev = c;
  264. c = *input++;
  265. }
  266. }
  267. switch (state) {
  268. case 0: /* Waiting for (unescaped) $ */
  269. if ((c == '\'') && (prev != '\\')) {
  270. state = 3;
  271. break;
  272. }
  273. if ((c == '$') && (prev != '\\')) {
  274. state++;
  275. } else {
  276. *(output++) = c;
  277. outputcnt--;
  278. }
  279. break;
  280. case 1: /* Waiting for ( */
  281. if (c == '(' || c == '{') {
  282. state++;
  283. varname_start = input;
  284. } else {
  285. state = 0;
  286. *(output++) = '$';
  287. outputcnt--;
  288. if (outputcnt) {
  289. *(output++) = c;
  290. outputcnt--;
  291. }
  292. }
  293. break;
  294. case 2: /* Waiting for ) */
  295. if (c == ')' || c == '}') {
  296. int i;
  297. char envname[CONFIG_SYS_CBSIZE], *envval;
  298. /* Varname # of chars */
  299. int envcnt = input - varname_start - 1;
  300. /* Get the varname */
  301. for (i = 0; i < envcnt; i++) {
  302. envname[i] = varname_start[i];
  303. }
  304. envname[i] = 0;
  305. /* Get its value */
  306. envval = getenv (envname);
  307. /* Copy into the line if it exists */
  308. if (envval != NULL)
  309. while ((*envval) && outputcnt) {
  310. *(output++) = *(envval++);
  311. outputcnt--;
  312. }
  313. /* Look for another '$' */
  314. state = 0;
  315. }
  316. break;
  317. case 3: /* Waiting for ' */
  318. if ((c == '\'') && (prev != '\\')) {
  319. state = 0;
  320. } else {
  321. *(output++) = c;
  322. outputcnt--;
  323. }
  324. break;
  325. }
  326. prev = c;
  327. }
  328. if (outputcnt)
  329. *output = 0;
  330. #ifdef DEBUG_PARSER
  331. printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
  332. strlen (output_start), output_start);
  333. #endif
  334. }
  335. /*
  336. * this is called from board_init() after the hardware has been set up
  337. * and is usable. That seems like a good time to do this.
  338. * Right now the return value is ignored.
  339. */
  340. int do_auto_update(void)
  341. {
  342. block_dev_desc_t *stor_dev = NULL;
  343. long sz;
  344. int i, res, cnt, old_ctrlc;
  345. char buffer[32];
  346. char str[80];
  347. int n;
  348. if (ide_dev_desc[0].type != DEV_TYPE_UNKNOWN) {
  349. stor_dev = get_dev ("ide", 0);
  350. if (stor_dev == NULL) {
  351. debug ("ide: unknown device\n");
  352. return -1;
  353. }
  354. }
  355. if (fat_register_device (stor_dev, 1) != 0) {
  356. debug ("Unable to register ide disk 0:1\n");
  357. return -1;
  358. }
  359. /*
  360. * Check if magic file is present
  361. */
  362. if ((n = do_fat_read (AU_MAGIC_FILE, buffer,
  363. sizeof(buffer), LS_NO)) <= 0) {
  364. debug ("No auto_update magic file (n=%d)\n", n);
  365. return -1;
  366. }
  367. #ifdef CONFIG_AUTO_UPDATE_SHOW
  368. board_auto_update_show (1);
  369. #endif
  370. puts("\nAutoUpdate Disk detected! Trying to update system...\n");
  371. /* make sure that we see CTRL-C and save the old state */
  372. old_ctrlc = disable_ctrlc (0);
  373. /* just loop thru all the possible files */
  374. for (i = 0; i < N_AU_IMAGES; i++) {
  375. /*
  376. * Try to expand the environment var in the fname
  377. */
  378. process_macros (au_image[i].name, str);
  379. strcpy (au_image[i].name, str);
  380. printf("Reading %s ...", au_image[i].name);
  381. /* just read the header */
  382. sz = do_fat_read (au_image[i].name, LOAD_ADDR,
  383. image_get_header_size (), LS_NO);
  384. debug ("read %s sz %ld hdr %d\n",
  385. au_image[i].name, sz, image_get_header_size ());
  386. if (sz <= 0 || sz < image_get_header_size ()) {
  387. puts(" not found\n");
  388. continue;
  389. }
  390. if (au_check_header_valid (i, sz) < 0) {
  391. puts(" header not valid\n");
  392. continue;
  393. }
  394. sz = do_fat_read (au_image[i].name, LOAD_ADDR,
  395. MAX_LOADSZ, LS_NO);
  396. debug ("read %s sz %ld hdr %d\n",
  397. au_image[i].name, sz, image_get_header_size ());
  398. if (sz <= 0 || sz <= image_get_header_size ()) {
  399. puts(" not found\n");
  400. continue;
  401. }
  402. if (au_check_cksum_valid (i, sz) < 0) {
  403. puts(" checksum not valid\n");
  404. continue;
  405. }
  406. puts(" done\n");
  407. do {
  408. res = au_do_update (i, sz);
  409. /* let the user break out of the loop */
  410. if (ctrlc() || had_ctrlc ()) {
  411. clear_ctrlc ();
  412. break;
  413. }
  414. cnt++;
  415. } while (res < 0);
  416. }
  417. /* restore the old state */
  418. disable_ctrlc (old_ctrlc);
  419. puts("AutoUpdate finished\n\n");
  420. #ifdef CONFIG_AUTO_UPDATE_SHOW
  421. board_auto_update_show (0);
  422. #endif
  423. return 0;
  424. }
  425. int auto_update(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  426. {
  427. do_auto_update();
  428. return 0;
  429. }
  430. U_BOOT_CMD(
  431. autoupd, 1, 1, auto_update,
  432. "Automatically update images",
  433. ""
  434. );
  435. #endif /* CONFIG_AUTO_UPDATE */