chknvm.c.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <?xml version='1.0' encoding='iso-8859-1'?>
  2. <!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
  3. <html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
  4. <head>
  5. <title>
  6. chknvm.c
  7. </title>
  8. <meta http-equiv='content-type' content='text/html;iso-8859-1'/>
  9. <meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
  10. <meta name='author' content='cmaier@cmassoc.net'/>
  11. <meta name='robots' content='noindex,nofollow'/>
  12. <link href='toolkit.css' rel='stylesheet' type='text/css'/>
  13. </head>
  14. <body>
  15. <div class='headerlink'>
  16. [<a href='chknvm2.c.html' title=' chknvm2.c '>PREV</a>]
  17. [<a href='toolkit.html' title=' Index '>HOME</a>]
  18. [<a href='chkpib2.c.html' title=' chkpib2.c '>NEXT</a>]
  19. </div>
  20. <pre>
  21. /*====================================================================*
  22. *
  23. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  24. *
  25. * All rights reserved.
  26. *
  27. * Redistribution and use in source and binary forms, with or
  28. * without modification, are permitted (subject to the limitations
  29. * in the disclaimer below) provided that the following conditions
  30. * are met:
  31. *
  32. * * Redistributions of source code must retain the above copyright
  33. * notice, this list of conditions and the following disclaimer.
  34. *
  35. * * Redistributions in binary form must reproduce the above
  36. * copyright notice, this list of conditions and the following
  37. * disclaimer in the documentation and/or other materials
  38. * provided with the distribution.
  39. *
  40. * * Neither the name of Qualcomm Atheros nor the names of
  41. * its contributors may be used to endorse or promote products
  42. * derived from this software without specific prior written
  43. * permission.
  44. *
  45. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
  46. * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
  47. * COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
  48. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  50. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  51. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  52. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  53. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  56. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  57. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. *
  60. *--------------------------------------------------------------------*/
  61. /*====================================================================*&quot;
  62. *
  63. * chknvm.c
  64. *
  65. *
  66. * Contributor(s):
  67. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  68. *
  69. *--------------------------------------------------------------------*/
  70. /*====================================================================*
  71. * system header files;
  72. *--------------------------------------------------------------------*/
  73. #include &lt;stdio.h&gt;
  74. #include &lt;stdlib.h&gt;
  75. #include &lt;unistd.h&gt;
  76. #include &lt;memory.h&gt;
  77. #include &lt;fcntl.h&gt;
  78. #include &lt;errno.h&gt;
  79. /*====================================================================*
  80. * custom header files;
  81. *--------------------------------------------------------------------*/
  82. #include &quot;../tools/getoptv.h&quot;
  83. #include &quot;../tools/memory.h&quot;
  84. #include &quot;../tools/flags.h&quot;
  85. #include &quot;../tools/error.h&quot;
  86. #include &quot;../tools/files.h&quot;
  87. #include &quot;../ram/sdram.h&quot;
  88. #include &quot;../nvm/nvm.h&quot;
  89. /*====================================================================*
  90. * custom source files;
  91. *--------------------------------------------------------------------*/
  92. #ifndef MAKEFILE
  93. #include &quot;../tools/getoptv.c&quot;
  94. #include &quot;../tools/putoptv.c&quot;
  95. #include &quot;../tools/version.c&quot;
  96. #include &quot;../tools/checksum32.c&quot;
  97. #include &quot;../tools/fdchecksum32.c&quot;
  98. #include &quot;../tools/strfbits.c&quot;
  99. #include &quot;../tools/error.c&quot;
  100. #endif
  101. #ifndef MAKEFILE
  102. #include &quot;../ram/sdrampeek.c&quot;
  103. #endif
  104. #ifndef MAKEFILE
  105. #include &quot;../nvm/nvm.c&quot;
  106. #include &quot;../nvm/nvmpeek.c&quot;
  107. #include &quot;../nvm/nvmpeek1.c&quot;
  108. #include &quot;../nvm/nvmpeek2.c&quot;
  109. #include &quot;../nvm/manifest.c&quot;
  110. #include &quot;../nvm/fdmanifest.c&quot;
  111. #endif
  112. /*====================================================================*
  113. * program constants;
  114. *--------------------------------------------------------------------*/
  115. #define HARDWARE 0
  116. #define SOFTWARE 1
  117. #define VER 2
  118. #define REV 3
  119. #define BUILD 6
  120. #define DATE 7
  121. /*====================================================================*
  122. *
  123. * unsigned string2vector (char ** vector, length, char * string, char c);
  124. *
  125. * convert string to a vector and return vector count; split string
  126. * on characer (c);
  127. *
  128. *
  129. * Contributor(s):
  130. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  131. *
  132. *--------------------------------------------------------------------*/
  133. static unsigned string2vector (char ** vector, char * string, char c)
  134. {
  135. char ** origin = vector;
  136. for (*vector++ = string; *string; string++)
  137. {
  138. if (*string == c)
  139. {
  140. *string++ = (char)(0);
  141. *vector++ = string--;
  142. }
  143. }
  144. *vector = (char *)(0);
  145. return ((unsigned)(vector - origin));
  146. }
  147. /*====================================================================*
  148. *
  149. * void firmware (signed fd, char const * filename, unsigned module, unsigned offset, flag_t flags);
  150. *
  151. *
  152. * Contributor(s):
  153. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  154. *
  155. *--------------------------------------------------------------------*/
  156. static void firmware (signed fd, char const * filename, unsigned module, unsigned offset, flag_t flags)
  157. {
  158. char memory [512];
  159. read (fd, memory, sizeof (memory));
  160. lseek (fd, (off_t)(0) - sizeof (memory), SEEK_CUR);
  161. if (_anyset (flags, NVM_FIRMWARE))
  162. {
  163. if ((*memory &gt; 0x20) &amp;&amp; (*memory &lt; 0x7F))
  164. {
  165. printf (&quot;%s (%d) %s\n&quot;, filename, module, memory);
  166. }
  167. else
  168. {
  169. printf (&quot;%s (%d) %s\n&quot;, filename, module, memory + offset);
  170. }
  171. }
  172. if (_anyset (flags, NVM_IDENTITY))
  173. {
  174. char * vector [16];
  175. char buffer [256];
  176. if ((* memory &gt; 0x20) &amp;&amp; (* memory &lt; 0x7f))
  177. {
  178. strncpy (buffer, memory, sizeof (buffer));
  179. }
  180. else
  181. {
  182. strncpy (buffer, memory + offset, sizeof (buffer));
  183. }
  184. string2vector (vector, buffer, '-');
  185. printf (&quot;%s &quot;, vector [HARDWARE]);
  186. printf (&quot;%04d &quot;, atoi (vector [BUILD]));
  187. printf (&quot;%s &quot;, vector [DATE]);
  188. printf (&quot;%s.&quot;, vector [VER]);
  189. printf (&quot;%s &quot;, vector [REV]);
  190. printf (&quot;%s (%d)\n&quot;, filename, module);
  191. return;
  192. }
  193. return;
  194. }
  195. /*====================================================================*
  196. *
  197. * signed nvmchain1 (signed fd, char const * filename, flag_t flags);
  198. *
  199. * validate a legcy PLC firmware file; return 0 on success or -1 on
  200. * error;
  201. *
  202. * keep as little information as possible in memory; this slows
  203. * validation but minimizes the resources needed at runtime so
  204. * that resource requirements do not grow with file size;
  205. *
  206. * the checksum of the entire header, including header checksum, is
  207. * always 0 for valid headers; similarly, the checksum of the module
  208. * and module checksum is always 0 for valid modules;
  209. *
  210. *
  211. * Contributor(s):
  212. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  213. *
  214. *--------------------------------------------------------------------*/
  215. static signed nvmchain1 (signed fd, char const * filename, flag_t flags)
  216. {
  217. struct nvm_header1 nvm_header;
  218. struct config_ram config_ram;
  219. unsigned module = 0;
  220. do
  221. {
  222. if (read (fd, &amp;nvm_header, sizeof (nvm_header)) != sizeof (nvm_header))
  223. {
  224. if (_allclr (flags, NVM_SILENCE))
  225. {
  226. error (0, errno, NVM_HDR_CANTREAD, filename, module);
  227. }
  228. return (-1);
  229. }
  230. if (LE32TOH (nvm_header.HEADERVERSION) != 0x60000000)
  231. {
  232. if (_allclr (flags, NVM_SILENCE))
  233. {
  234. error (0, errno, NVM_HDR_VERSION, filename, module);
  235. }
  236. return (-1);
  237. }
  238. if (checksum32 (&amp;nvm_header, sizeof (nvm_header), 0))
  239. {
  240. if (_allclr (flags, NVM_SILENCE))
  241. {
  242. error (0, errno, NVM_HDR_CHECKSUM, filename, module);
  243. }
  244. return (-1);
  245. }
  246. if (_anyset (flags, NVM_VERBOSE))
  247. {
  248. printf (&quot;------- %s (%d) -------\n&quot;, filename, module);
  249. nvmpeek1 (&amp;nvm_header);
  250. }
  251. if (nvm_header.HEADERMINORVERSION)
  252. {
  253. if (LE32TOH (nvm_header.IMAGETYPE) == NVM_IMAGE_CONFIG_SYNOPSIS)
  254. {
  255. if (_anyset (flags, NVM_SDRAM))
  256. {
  257. printf (&quot;------- %s (%d) -------\n&quot;, filename, module);
  258. read (fd, &amp;config_ram, sizeof (config_ram));
  259. lseek (fd, (off_t)(0) - sizeof (config_ram), SEEK_CUR);
  260. sdrampeek (&amp;config_ram);
  261. }
  262. }
  263. else if (LE32TOH (nvm_header.IMAGETYPE) == NVM_IMAGE_FIRMWARE)
  264. {
  265. firmware (fd, filename, module, 0x70, flags);
  266. }
  267. }
  268. else if (!module)
  269. {
  270. if (_anyset (flags, NVM_SDRAM))
  271. {
  272. printf (&quot;------- %s (%d) -------\n&quot;, filename, module);
  273. read (fd, &amp;config_ram, sizeof (config_ram));
  274. lseek (fd, (off_t)(0) - sizeof (config_ram), SEEK_CUR);
  275. sdrampeek (&amp;config_ram);
  276. }
  277. }
  278. else if (!nvm_header.NEXTHEADER)
  279. {
  280. firmware (fd, filename, module, 0x70, flags);
  281. }
  282. if (fdchecksum32 (fd, LE32TOH (nvm_header.IMAGELENGTH), nvm_header.IMAGECHECKSUM))
  283. {
  284. if (_allclr (flags, NVM_SILENCE))
  285. {
  286. error (0, errno, NVM_IMG_CHECKSUM, filename, module);
  287. }
  288. return (-1);
  289. }
  290. module++;
  291. }
  292. while (nvm_header.NEXTHEADER);
  293. if (lseek (fd, 0, SEEK_CUR) != lseek (fd, 0, SEEK_END))
  294. {
  295. if (_allclr (flags, NVM_SILENCE))
  296. {
  297. error (0, errno, NVM_HDR_LINK, filename, module);
  298. }
  299. return (-1);
  300. }
  301. return (0);
  302. }
  303. /*====================================================================*
  304. *
  305. * signed nvmchain2 (signed fd, char const * filename, flag_t flags);
  306. *
  307. * validate a PLC image file; return 0 on success or -1 on error;
  308. *
  309. * keep as little information as possible in memory; this slows
  310. * validation but minimizes the resources needed at runtime so
  311. * that resource requirements do not grow with file size;
  312. *
  313. * the checksum of the entire header, including header checksum, is
  314. * always 0 for valid headers; similarly, the checksum of the module
  315. * and module checksum is always 0 for valid modules;
  316. *
  317. *
  318. * Contributor(s):
  319. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  320. *
  321. *--------------------------------------------------------------------*/
  322. static signed nvmchain2 (signed fd, char const * filename, flag_t flags)
  323. {
  324. struct nvm_header2 nvm_header;
  325. unsigned module = 0;
  326. uint32_t origin = ~0;
  327. uint32_t offset = 0;
  328. do
  329. {
  330. if (read (fd, &amp;nvm_header, sizeof (nvm_header)) != sizeof (nvm_header))
  331. {
  332. if (_allclr (flags, NVM_SILENCE))
  333. {
  334. error (0, errno, NVM_HDR_CANTREAD, filename, module);
  335. }
  336. return (-1);
  337. }
  338. if (LE16TOH (nvm_header.MajorVersion) != 1)
  339. {
  340. if (_allclr (flags, NVM_SILENCE))
  341. {
  342. error (0, errno, NVM_HDR_VERSION, filename, module);
  343. }
  344. return (-1);
  345. }
  346. if (LE16TOH (nvm_header.MinorVersion) != 1)
  347. {
  348. if (_allclr (flags, NVM_SILENCE))
  349. {
  350. error (0, errno, NVM_HDR_VERSION, filename, module);
  351. }
  352. return (-1);
  353. }
  354. if (checksum32 (&amp;nvm_header, sizeof (nvm_header), 0))
  355. {
  356. if (_allclr (flags, NVM_SILENCE))
  357. {
  358. error (0, errno, NVM_HDR_CHECKSUM, filename, module);
  359. }
  360. return (-1);
  361. }
  362. if (LE32TOH (nvm_header.PrevHeader) != origin)
  363. {
  364. if (_allclr (flags, NVM_SILENCE))
  365. {
  366. error (0, errno, NVM_HDR_LINK, filename, module);
  367. }
  368. return (-1);
  369. }
  370. if (_anyset (flags, NVM_VERBOSE))
  371. {
  372. printf (&quot;------- %s (%d) -------\n&quot;, filename, module);
  373. nvmpeek2 (&amp;nvm_header);
  374. }
  375. if (LE32TOH (nvm_header.ImageType) == NVM_IMAGE_MANIFEST)
  376. {
  377. if (_anyset (flags, NVM_MANIFEST))
  378. {
  379. fdmanifest (fd, filename, &amp;nvm_header, module);
  380. return (0);
  381. }
  382. }
  383. if (fdchecksum32 (fd, LE32TOH (nvm_header.ImageLength), nvm_header.ImageChecksum))
  384. {
  385. if (_allclr (flags, NVM_SILENCE))
  386. {
  387. error (0, errno, NVM_IMG_CHECKSUM, filename, module);
  388. }
  389. return (-1);
  390. }
  391. origin = offset;
  392. offset = LE32TOH (nvm_header.NextHeader);
  393. module++;
  394. }
  395. while (~nvm_header.NextHeader);
  396. if (lseek (fd, 0, SEEK_CUR) != lseek (fd, 0, SEEK_END))
  397. {
  398. if (_allclr (flags, NVM_SILENCE))
  399. {
  400. error (0, errno, NVM_HDR_LINK, filename, module);
  401. }
  402. return (-1);
  403. }
  404. return (0);
  405. }
  406. /*====================================================================*
  407. *
  408. * signed chknvm (char const * filename, flag_t flags);
  409. *
  410. * validate a PLC firmware module file; keep as little information
  411. * as possible in memory; this slows validation but minimizes the
  412. * resources needed at runtime; resource requirements do not grow
  413. * with file size;
  414. *
  415. * determine file format based on module header version then rewind
  416. * the file and call the appropriate chknvm;
  417. *
  418. *
  419. * Contributor(s):
  420. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  421. *
  422. *--------------------------------------------------------------------*/
  423. static signed chknvm (char const * filename, flag_t flags)
  424. {
  425. uint32_t version;
  426. signed status;
  427. signed fd;
  428. if ((fd = open (filename, O_BINARY|O_RDONLY)) == -1)
  429. {
  430. if (_allclr (flags, NVM_SILENCE))
  431. {
  432. error (0, errno, FILE_CANTOPEN, filename);
  433. }
  434. return (-1);
  435. }
  436. if (read (fd, &amp;version, sizeof (version)) != sizeof (version))
  437. {
  438. if (_allclr (flags, NVM_SILENCE))
  439. {
  440. error (0, errno, FILE_CANTREAD, filename);
  441. }
  442. return (-1);
  443. }
  444. if (lseek (fd, 0, SEEK_SET))
  445. {
  446. if (_allclr (flags, NVM_SILENCE))
  447. {
  448. error (0, errno, FILE_CANTHOME, filename);
  449. }
  450. return (-1);
  451. }
  452. if (LE32TOH (version) == 0x60000000)
  453. {
  454. status = nvmchain1 (fd, filename, flags);
  455. }
  456. else
  457. {
  458. status = nvmchain2 (fd, filename, flags);
  459. }
  460. close (fd);
  461. return (status);
  462. }
  463. /*====================================================================*
  464. *
  465. * int main (int argc, char const * argv []);
  466. *
  467. * validate a PLC firmware image file; keep as little information
  468. * as possible in memory; this slows validation but minimizes the
  469. * resources needed at runtime; resource requirements do not grow
  470. * with file size;
  471. *
  472. *
  473. * Contributor(s):
  474. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  475. *
  476. *--------------------------------------------------------------------*/
  477. int main (int argc, char const * argv [])
  478. {
  479. static char const * optv [] =
  480. {
  481. &quot;imqrsv&quot;,
  482. &quot;file [file] [...]&quot;,
  483. &quot;Qualcomm Atheros PLC Image File Validator&quot;,
  484. &quot;i\tprint firmware identity string&quot;,
  485. &quot;m\tdisplay manifest&quot;,
  486. &quot;q\tsuppress messages&quot;,
  487. &quot;r\tprint firmware revision string&quot;,
  488. &quot;s\tprint SDRAM configuration blocks&quot;,
  489. &quot;v\tverbose messages&quot;,
  490. (char const *) (0)
  491. };
  492. signed state = 0;
  493. flag_t flags = (flag_t)(0);
  494. signed c;
  495. optind = 1;
  496. while ((c = getoptv (argc, argv, optv)) != -1)
  497. {
  498. switch ((char) (c))
  499. {
  500. case 'i':
  501. _setbits (flags, NVM_IDENTITY);
  502. break;
  503. case 'r':
  504. _setbits (flags, NVM_FIRMWARE);
  505. break;
  506. case 'm':
  507. _setbits (flags, NVM_MANIFEST);
  508. break;
  509. case 's':
  510. _setbits (flags, NVM_SDRAM);
  511. break;
  512. case 'q':
  513. _setbits (flags, NVM_SILENCE);
  514. break;
  515. case 'v':
  516. _setbits (flags, NVM_VERBOSE);
  517. break;
  518. default:
  519. break;
  520. }
  521. }
  522. argc -= optind;
  523. argv += optind;
  524. while ((argc) &amp;&amp; (* argv))
  525. {
  526. if (chknvm (* argv, flags))
  527. {
  528. state = 1;
  529. }
  530. else if (_allclr (flags, (NVM_VERBOSE|NVM_SILENCE|NVM_MANIFEST|NVM_FIRMWARE|NVM_IDENTITY|NVM_SDRAM)))
  531. {
  532. printf (&quot;file %s looks good\n&quot;, * argv);
  533. }
  534. argc--;
  535. argv++;
  536. }
  537. return (state);
  538. }
  539. </pre>
  540. <div class='footerlink'>
  541. [<a href='chknvm2.c.html' title=' chknvm2.c '>PREV</a>]
  542. [<a href='toolkit.html' title=' Index '>HOME</a>]
  543. [<a href='chkpib2.c.html' title=' chkpib2.c '>NEXT</a>]
  544. </div>
  545. </body>
  546. </html>