auto_update.c 13 KB

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