auto_update.c 12 KB

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