fw_env.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2010
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (C) Copyright 2008
  7. * Guennadi Liakhovetski, DENX Software Engineering, lg@denx.de.
  8. */
  9. #define _GNU_SOURCE
  10. #include <compiler.h>
  11. #include <errno.h>
  12. #include <env_flags.h>
  13. #include <fcntl.h>
  14. #include <libgen.h>
  15. #include <linux/fs.h>
  16. #include <linux/stringify.h>
  17. #include <ctype.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stddef.h>
  21. #include <string.h>
  22. #include <sys/types.h>
  23. #include <sys/ioctl.h>
  24. #include <sys/stat.h>
  25. #include <unistd.h>
  26. #include <dirent.h>
  27. #ifdef MTD_OLD
  28. # include <stdint.h>
  29. # include <linux/mtd/mtd.h>
  30. #else
  31. # define __user /* nothing */
  32. # include <mtd/mtd-user.h>
  33. #endif
  34. #include <mtd/ubi-user.h>
  35. #include "fw_env_private.h"
  36. #include "fw_env.h"
  37. struct env_opts default_opts = {
  38. #ifdef CONFIG_FILE
  39. .config_file = CONFIG_FILE
  40. #endif
  41. };
  42. #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
  43. #define min(x, y) ({ \
  44. typeof(x) _min1 = (x); \
  45. typeof(y) _min2 = (y); \
  46. (void) (&_min1 == &_min2); \
  47. _min1 < _min2 ? _min1 : _min2; })
  48. struct envdev_s {
  49. const char *devname; /* Device name */
  50. long long devoff; /* Device offset */
  51. ulong env_size; /* environment size */
  52. ulong erase_size; /* device erase size */
  53. ulong env_sectors; /* number of environment sectors */
  54. uint8_t mtd_type; /* type of the MTD device */
  55. int is_ubi; /* set if we use UBI volume */
  56. };
  57. static struct envdev_s envdevices[2] = {
  58. {
  59. .mtd_type = MTD_ABSENT,
  60. }, {
  61. .mtd_type = MTD_ABSENT,
  62. },
  63. };
  64. static int dev_current;
  65. #define DEVNAME(i) envdevices[(i)].devname
  66. #define DEVOFFSET(i) envdevices[(i)].devoff
  67. #define ENVSIZE(i) envdevices[(i)].env_size
  68. #define DEVESIZE(i) envdevices[(i)].erase_size
  69. #define ENVSECTORS(i) envdevices[(i)].env_sectors
  70. #define DEVTYPE(i) envdevices[(i)].mtd_type
  71. #define IS_UBI(i) envdevices[(i)].is_ubi
  72. #define CUR_ENVSIZE ENVSIZE(dev_current)
  73. #define USE_THE_EMMC 0
  74. static unsigned long usable_envsize;
  75. #define ENV_SIZE usable_envsize
  76. struct env_image_single {
  77. uint32_t crc; /* CRC32 over data bytes */
  78. char data[];
  79. };
  80. struct env_image_redundant {
  81. uint32_t crc; /* CRC32 over data bytes */
  82. unsigned char flags; /* active or obsolete */
  83. char data[];
  84. };
  85. enum flag_scheme {
  86. FLAG_NONE,
  87. FLAG_BOOLEAN,
  88. FLAG_INCREMENTAL,
  89. };
  90. struct environment {
  91. void *image;
  92. uint32_t *crc;
  93. unsigned char *flags;
  94. char *data;
  95. enum flag_scheme flag_scheme;
  96. };
  97. static struct environment environment = {
  98. .flag_scheme = FLAG_NONE,
  99. };
  100. static int have_redund_env;
  101. static unsigned char active_flag = 1;
  102. /* obsolete_flag must be 0 to efficiently set it on NOR flash without erasing */
  103. static unsigned char obsolete_flag = 0;
  104. #define DEFAULT_ENV_INSTANCE_STATIC
  105. #include <env_default.h>
  106. #define UBI_DEV_START "/dev/ubi"
  107. #define UBI_SYSFS "/sys/class/ubi"
  108. #define UBI_VOL_NAME_PATT "ubi%d_%d"
  109. static int is_ubi_devname(const char *devname)
  110. {
  111. return !strncmp(devname, UBI_DEV_START, sizeof(UBI_DEV_START) - 1);
  112. }
  113. static int ubi_check_volume_sysfs_name(const char *volume_sysfs_name,
  114. const char *volname)
  115. {
  116. char path[256];
  117. FILE *file;
  118. char *name;
  119. int ret;
  120. strcpy(path, UBI_SYSFS "/");
  121. strcat(path, volume_sysfs_name);
  122. strcat(path, "/name");
  123. file = fopen(path, "r");
  124. if (!file)
  125. return -1;
  126. ret = fscanf(file, "%ms", &name);
  127. fclose(file);
  128. if (ret <= 0 || !name) {
  129. fprintf(stderr,
  130. "Failed to read from file %s, ret = %d, name = %s\n",
  131. path, ret, name);
  132. return -1;
  133. }
  134. if (!strcmp(name, volname)) {
  135. free(name);
  136. return 0;
  137. }
  138. free(name);
  139. return -1;
  140. }
  141. static int ubi_get_volnum_by_name(int devnum, const char *volname)
  142. {
  143. DIR *sysfs_ubi;
  144. struct dirent *dirent;
  145. int ret;
  146. int tmp_devnum;
  147. int volnum;
  148. sysfs_ubi = opendir(UBI_SYSFS);
  149. if (!sysfs_ubi)
  150. return -1;
  151. #ifdef DEBUG
  152. fprintf(stderr, "Looking for volume name \"%s\"\n", volname);
  153. #endif
  154. while (1) {
  155. dirent = readdir(sysfs_ubi);
  156. if (!dirent)
  157. return -1;
  158. ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT,
  159. &tmp_devnum, &volnum);
  160. if (ret == 2 && devnum == tmp_devnum) {
  161. if (ubi_check_volume_sysfs_name(dirent->d_name,
  162. volname) == 0)
  163. return volnum;
  164. }
  165. }
  166. return -1;
  167. }
  168. static int ubi_get_devnum_by_devname(const char *devname)
  169. {
  170. int devnum;
  171. int ret;
  172. ret = sscanf(devname + sizeof(UBI_DEV_START) - 1, "%d", &devnum);
  173. if (ret != 1)
  174. return -1;
  175. return devnum;
  176. }
  177. static const char *ubi_get_volume_devname(const char *devname,
  178. const char *volname)
  179. {
  180. char *volume_devname;
  181. int volnum;
  182. int devnum;
  183. int ret;
  184. devnum = ubi_get_devnum_by_devname(devname);
  185. if (devnum < 0)
  186. return NULL;
  187. volnum = ubi_get_volnum_by_name(devnum, volname);
  188. if (volnum < 0)
  189. return NULL;
  190. ret = asprintf(&volume_devname, "%s_%d", devname, volnum);
  191. if (ret < 0)
  192. return NULL;
  193. #ifdef DEBUG
  194. fprintf(stderr, "Found ubi volume \"%s:%s\" -> %s\n",
  195. devname, volname, volume_devname);
  196. #endif
  197. return volume_devname;
  198. }
  199. static void ubi_check_dev(unsigned int dev_id)
  200. {
  201. char *devname = (char *)DEVNAME(dev_id);
  202. char *pname;
  203. const char *volname = NULL;
  204. const char *volume_devname;
  205. if (!is_ubi_devname(DEVNAME(dev_id)))
  206. return;
  207. IS_UBI(dev_id) = 1;
  208. for (pname = devname; *pname != '\0'; pname++) {
  209. if (*pname == ':') {
  210. *pname = '\0';
  211. volname = pname + 1;
  212. break;
  213. }
  214. }
  215. if (volname) {
  216. /* Let's find real volume device name */
  217. volume_devname = ubi_get_volume_devname(devname, volname);
  218. if (!volume_devname) {
  219. fprintf(stderr, "Didn't found ubi volume \"%s\"\n",
  220. volname);
  221. return;
  222. }
  223. free(devname);
  224. DEVNAME(dev_id) = volume_devname;
  225. }
  226. }
  227. static int ubi_update_start(int fd, int64_t bytes)
  228. {
  229. if (ioctl(fd, UBI_IOCVOLUP, &bytes))
  230. return -1;
  231. return 0;
  232. }
  233. static int ubi_read(int fd, void *buf, size_t count)
  234. {
  235. ssize_t ret;
  236. while (count > 0) {
  237. ret = read(fd, buf, count);
  238. if (ret > 0) {
  239. count -= ret;
  240. buf += ret;
  241. continue;
  242. }
  243. if (ret == 0) {
  244. /*
  245. * Happens in case of too short volume data size. If we
  246. * return error status we will fail it will be treated
  247. * as UBI device error.
  248. *
  249. * Leave catching this error to CRC check.
  250. */
  251. fprintf(stderr, "Warning: end of data on ubi volume\n");
  252. return 0;
  253. } else if (errno == EBADF) {
  254. /*
  255. * Happens in case of corrupted volume. The same as
  256. * above, we cannot return error now, as we will still
  257. * be able to successfully write environment later.
  258. */
  259. fprintf(stderr, "Warning: corrupted volume?\n");
  260. return 0;
  261. } else if (errno == EINTR) {
  262. continue;
  263. }
  264. fprintf(stderr, "Cannot read %u bytes from ubi volume, %s\n",
  265. (unsigned int)count, strerror(errno));
  266. return -1;
  267. }
  268. return 0;
  269. }
  270. static int ubi_write(int fd, const void *buf, size_t count)
  271. {
  272. ssize_t ret;
  273. while (count > 0) {
  274. ret = write(fd, buf, count);
  275. if (ret <= 0) {
  276. if (ret < 0 && errno == EINTR)
  277. continue;
  278. fprintf(stderr, "Cannot write %u bytes to ubi volume\n",
  279. (unsigned int)count);
  280. return -1;
  281. }
  282. count -= ret;
  283. buf += ret;
  284. }
  285. return 0;
  286. }
  287. static int flash_io(int mode);
  288. static int parse_config(struct env_opts *opts);
  289. #if defined(CONFIG_FILE)
  290. static int get_config(char *);
  291. #endif
  292. static char *skip_chars(char *s)
  293. {
  294. for (; *s != '\0'; s++) {
  295. if (isblank(*s) || *s == '=')
  296. return s;
  297. }
  298. return NULL;
  299. }
  300. static char *skip_blanks(char *s)
  301. {
  302. for (; *s != '\0'; s++) {
  303. if (!isblank(*s))
  304. return s;
  305. }
  306. return NULL;
  307. }
  308. /*
  309. * s1 is either a simple 'name', or a 'name=value' pair.
  310. * s2 is a 'name=value' pair.
  311. * If the names match, return the value of s2, else NULL.
  312. */
  313. static char *envmatch(char *s1, char *s2)
  314. {
  315. if (s1 == NULL || s2 == NULL)
  316. return NULL;
  317. while (*s1 == *s2++)
  318. if (*s1++ == '=')
  319. return s2;
  320. if (*s1 == '\0' && *(s2 - 1) == '=')
  321. return s2;
  322. return NULL;
  323. }
  324. /**
  325. * Search the environment for a variable.
  326. * Return the value, if found, or NULL, if not found.
  327. */
  328. char *fw_getenv(char *name)
  329. {
  330. char *env, *nxt;
  331. for (env = environment.data; *env; env = nxt + 1) {
  332. char *val;
  333. for (nxt = env; *nxt; ++nxt) {
  334. if (nxt >= &environment.data[ENV_SIZE]) {
  335. fprintf(stderr, "## Error: "
  336. "environment not terminated\n");
  337. return NULL;
  338. }
  339. }
  340. val = envmatch(name, env);
  341. if (!val)
  342. continue;
  343. return val;
  344. }
  345. return NULL;
  346. }
  347. /*
  348. * Search the default environment for a variable.
  349. * Return the value, if found, or NULL, if not found.
  350. */
  351. char *fw_getdefenv(char *name)
  352. {
  353. char *env, *nxt;
  354. for (env = default_environment; *env; env = nxt + 1) {
  355. char *val;
  356. for (nxt = env; *nxt; ++nxt) {
  357. if (nxt >= &default_environment[ENV_SIZE]) {
  358. fprintf(stderr, "## Error: "
  359. "default environment not terminated\n");
  360. return NULL;
  361. }
  362. }
  363. val = envmatch(name, env);
  364. if (!val)
  365. continue;
  366. return val;
  367. }
  368. return NULL;
  369. }
  370. /*
  371. * Print the current definition of one, or more, or all
  372. * environment variables
  373. */
  374. int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
  375. {
  376. int i, rc = 0;
  377. if (value_only && argc != 1) {
  378. fprintf(stderr,
  379. "## Error: `-n'/`--noheader' option requires exactly one argument\n");
  380. return -1;
  381. }
  382. if (!opts)
  383. opts = &default_opts;
  384. if (fw_env_open(opts))
  385. return -1;
  386. if (argc == 0) { /* Print all env variables */
  387. char *env, *nxt;
  388. for (env = environment.data; *env; env = nxt + 1) {
  389. for (nxt = env; *nxt; ++nxt) {
  390. if (nxt >= &environment.data[ENV_SIZE]) {
  391. fprintf(stderr, "## Error: "
  392. "environment not terminated\n");
  393. return -1;
  394. }
  395. }
  396. printf("%s\n", env);
  397. }
  398. fw_env_close(opts);
  399. return 0;
  400. }
  401. for (i = 0; i < argc; ++i) { /* print a subset of env variables */
  402. char *name = argv[i];
  403. char *val = NULL;
  404. val = fw_getenv(name);
  405. if (!val) {
  406. fprintf(stderr, "## Error: \"%s\" not defined\n", name);
  407. rc = -1;
  408. continue;
  409. }
  410. if (value_only) {
  411. puts(val);
  412. break;
  413. }
  414. printf("%s=%s\n", name, val);
  415. }
  416. fw_env_close(opts);
  417. return rc;
  418. }
  419. int fw_env_flush(struct env_opts *opts)
  420. {
  421. if (!opts)
  422. opts = &default_opts;
  423. /*
  424. * Update CRC
  425. */
  426. *environment.crc = crc32(0, (uint8_t *) environment.data, ENV_SIZE);
  427. /* write environment back to flash */
  428. if (flash_io(O_RDWR)) {
  429. fprintf(stderr, "Error: can't write fw_env to flash\n");
  430. return -1;
  431. }
  432. return 0;
  433. }
  434. /*
  435. * Set/Clear a single variable in the environment.
  436. * This is called in sequence to update the environment
  437. * in RAM without updating the copy in flash after each set
  438. */
  439. int fw_env_write(char *name, char *value)
  440. {
  441. int len;
  442. char *env, *nxt;
  443. char *oldval = NULL;
  444. int deleting, creating, overwriting;
  445. /*
  446. * search if variable with this name already exists
  447. */
  448. for (nxt = env = environment.data; *env; env = nxt + 1) {
  449. for (nxt = env; *nxt; ++nxt) {
  450. if (nxt >= &environment.data[ENV_SIZE]) {
  451. fprintf(stderr, "## Error: "
  452. "environment not terminated\n");
  453. errno = EINVAL;
  454. return -1;
  455. }
  456. }
  457. oldval = envmatch(name, env);
  458. if (oldval)
  459. break;
  460. }
  461. deleting = (oldval && !(value && strlen(value)));
  462. creating = (!oldval && (value && strlen(value)));
  463. overwriting = (oldval && (value && strlen(value)));
  464. /* check for permission */
  465. if (deleting) {
  466. if (env_flags_validate_varaccess(name,
  467. ENV_FLAGS_VARACCESS_PREVENT_DELETE)) {
  468. printf("Can't delete \"%s\"\n", name);
  469. errno = EROFS;
  470. return -1;
  471. }
  472. } else if (overwriting) {
  473. if (env_flags_validate_varaccess(name,
  474. ENV_FLAGS_VARACCESS_PREVENT_OVERWR)) {
  475. printf("Can't overwrite \"%s\"\n", name);
  476. errno = EROFS;
  477. return -1;
  478. } else if (env_flags_validate_varaccess(name,
  479. ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR)) {
  480. const char *defval = fw_getdefenv(name);
  481. if (defval == NULL)
  482. defval = "";
  483. if (strcmp(oldval, defval)
  484. != 0) {
  485. printf("Can't overwrite \"%s\"\n", name);
  486. errno = EROFS;
  487. return -1;
  488. }
  489. }
  490. } else if (creating) {
  491. if (env_flags_validate_varaccess(name,
  492. ENV_FLAGS_VARACCESS_PREVENT_CREATE)) {
  493. printf("Can't create \"%s\"\n", name);
  494. errno = EROFS;
  495. return -1;
  496. }
  497. } else
  498. /* Nothing to do */
  499. return 0;
  500. if (deleting || overwriting) {
  501. if (*++nxt == '\0') {
  502. *env = '\0';
  503. } else {
  504. for (;;) {
  505. *env = *nxt++;
  506. if ((*env == '\0') && (*nxt == '\0'))
  507. break;
  508. ++env;
  509. }
  510. }
  511. *++env = '\0';
  512. }
  513. /* Delete only ? */
  514. if (!value || !strlen(value))
  515. return 0;
  516. /*
  517. * Append new definition at the end
  518. */
  519. for (env = environment.data; *env || *(env + 1); ++env)
  520. ;
  521. if (env > environment.data)
  522. ++env;
  523. /*
  524. * Overflow when:
  525. * "name" + "=" + "val" +"\0\0" > CUR_ENVSIZE - (env-environment)
  526. */
  527. len = strlen(name) + 2;
  528. /* add '=' for first arg, ' ' for all others */
  529. len += strlen(value) + 1;
  530. if (len > (&environment.data[ENV_SIZE] - env)) {
  531. fprintf(stderr,
  532. "Error: environment overflow, \"%s\" deleted\n", name);
  533. return -1;
  534. }
  535. while ((*env = *name++) != '\0')
  536. env++;
  537. *env = '=';
  538. while ((*++env = *value++) != '\0')
  539. ;
  540. /* end is marked with double '\0' */
  541. *++env = '\0';
  542. return 0;
  543. }
  544. /*
  545. * Deletes or sets environment variables. Returns -1 and sets errno error codes:
  546. * 0 - OK
  547. * EINVAL - need at least 1 argument
  548. * EROFS - certain variables ("ethaddr", "serial#") cannot be
  549. * modified or deleted
  550. *
  551. */
  552. int fw_env_set(int argc, char *argv[], struct env_opts *opts)
  553. {
  554. int i;
  555. size_t len;
  556. char *name, **valv;
  557. char *oldval;
  558. char *value = NULL;
  559. int valc;
  560. int ret;
  561. if (!opts)
  562. opts = &default_opts;
  563. if (argc < 1) {
  564. fprintf(stderr, "## Error: variable name missing\n");
  565. errno = EINVAL;
  566. return -1;
  567. }
  568. if (fw_env_open(opts)) {
  569. fprintf(stderr, "Error: environment not initialized\n");
  570. return -1;
  571. }
  572. name = argv[0];
  573. valv = argv + 1;
  574. valc = argc - 1;
  575. if (env_flags_validate_env_set_params(name, valv, valc) < 0) {
  576. fw_env_close(opts);
  577. return -1;
  578. }
  579. len = 0;
  580. for (i = 0; i < valc; ++i) {
  581. char *val = valv[i];
  582. size_t val_len = strlen(val);
  583. if (value)
  584. value[len - 1] = ' ';
  585. oldval = value;
  586. value = realloc(value, len + val_len + 1);
  587. if (!value) {
  588. fprintf(stderr,
  589. "Cannot malloc %zu bytes: %s\n",
  590. len, strerror(errno));
  591. free(oldval);
  592. return -1;
  593. }
  594. memcpy(value + len, val, val_len);
  595. len += val_len;
  596. value[len++] = '\0';
  597. }
  598. fw_env_write(name, value);
  599. free(value);
  600. ret = fw_env_flush(opts);
  601. fw_env_close(opts);
  602. return ret;
  603. }
  604. /*
  605. * Parse a file and configure the u-boot variables.
  606. * The script file has a very simple format, as follows:
  607. *
  608. * Each line has a couple with name, value:
  609. * <white spaces>variable_name<white spaces>variable_value
  610. *
  611. * Both variable_name and variable_value are interpreted as strings.
  612. * Any character after <white spaces> and before ending \r\n is interpreted
  613. * as variable's value (no comment allowed on these lines !)
  614. *
  615. * Comments are allowed if the first character in the line is #
  616. *
  617. * Returns -1 and sets errno error codes:
  618. * 0 - OK
  619. * -1 - Error
  620. */
  621. int fw_parse_script(char *fname, struct env_opts *opts)
  622. {
  623. FILE *fp;
  624. char *line = NULL;
  625. size_t linesize = 0;
  626. char *name;
  627. char *val;
  628. int lineno = 0;
  629. int len;
  630. int ret = 0;
  631. if (!opts)
  632. opts = &default_opts;
  633. if (fw_env_open(opts)) {
  634. fprintf(stderr, "Error: environment not initialized\n");
  635. return -1;
  636. }
  637. if (strcmp(fname, "-") == 0)
  638. fp = stdin;
  639. else {
  640. fp = fopen(fname, "r");
  641. if (fp == NULL) {
  642. fprintf(stderr, "I cannot open %s for reading\n",
  643. fname);
  644. return -1;
  645. }
  646. }
  647. while ((len = getline(&line, &linesize, fp)) != -1) {
  648. lineno++;
  649. /*
  650. * Read a whole line from the file. If the line is not
  651. * terminated, reports an error and exit.
  652. */
  653. if (line[len - 1] != '\n') {
  654. fprintf(stderr,
  655. "Line %d not correctly terminated\n",
  656. lineno);
  657. ret = -1;
  658. break;
  659. }
  660. /* Drop ending line feed / carriage return */
  661. line[--len] = '\0';
  662. if (len && line[len - 1] == '\r')
  663. line[--len] = '\0';
  664. /* Skip comment or empty lines */
  665. if (len == 0 || line[0] == '#')
  666. continue;
  667. /*
  668. * Search for variable's name remove leading whitespaces
  669. */
  670. name = skip_blanks(line);
  671. if (!name)
  672. continue;
  673. /* The first white space is the end of variable name */
  674. val = skip_chars(name);
  675. len = strlen(name);
  676. if (val) {
  677. *val++ = '\0';
  678. if ((val - name) < len)
  679. val = skip_blanks(val);
  680. else
  681. val = NULL;
  682. }
  683. #ifdef DEBUG
  684. fprintf(stderr, "Setting %s : %s\n",
  685. name, val ? val : " removed");
  686. #endif
  687. if (env_flags_validate_type(name, val) < 0) {
  688. ret = -1;
  689. break;
  690. }
  691. /*
  692. * If there is an error setting a variable,
  693. * try to save the environment and returns an error
  694. */
  695. if (fw_env_write(name, val)) {
  696. fprintf(stderr,
  697. "fw_env_write returns with error : %s\n",
  698. strerror(errno));
  699. ret = -1;
  700. break;
  701. }
  702. }
  703. free(line);
  704. /* Close file if not stdin */
  705. if (strcmp(fname, "-") != 0)
  706. fclose(fp);
  707. ret |= fw_env_flush(opts);
  708. fw_env_close(opts);
  709. return ret;
  710. }
  711. /**
  712. * environment_end() - compute offset of first byte right after environment
  713. * @dev - index of enviroment buffer
  714. * Return:
  715. * device offset of first byte right after environment
  716. */
  717. off_t environment_end(int dev)
  718. {
  719. /* environment is block aligned */
  720. return DEVOFFSET(dev) + ENVSECTORS(dev) * DEVESIZE(dev);
  721. }
  722. /*
  723. * Test for bad block on NAND, just returns 0 on NOR, on NAND:
  724. * 0 - block is good
  725. * > 0 - block is bad
  726. * < 0 - failed to test
  727. */
  728. static int flash_bad_block(int fd, uint8_t mtd_type, loff_t blockstart)
  729. {
  730. if (mtd_type == MTD_NANDFLASH) {
  731. int badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart);
  732. if (badblock < 0) {
  733. perror("Cannot read bad block mark");
  734. return badblock;
  735. }
  736. if (badblock) {
  737. #ifdef DEBUG
  738. fprintf(stderr, "Bad block at 0x%llx, skipping\n",
  739. (unsigned long long)blockstart);
  740. #endif
  741. return badblock;
  742. }
  743. }
  744. return 0;
  745. }
  746. /*
  747. * Read data from flash at an offset into a provided buffer. On NAND it skips
  748. * bad blocks but makes sure it stays within ENVSECTORS (dev) starting from
  749. * the DEVOFFSET (dev) block. On NOR the loop is only run once.
  750. */
  751. static int flash_read_buf(int dev, int fd, void *buf, size_t count,
  752. off_t offset)
  753. {
  754. size_t blocklen; /* erase / write length - one block on NAND,
  755. 0 on NOR */
  756. size_t processed = 0; /* progress counter */
  757. size_t readlen = count; /* current read length */
  758. off_t block_seek; /* offset inside the current block to the start
  759. of the data */
  760. loff_t blockstart; /* running start of the current block -
  761. MEMGETBADBLOCK needs 64 bits */
  762. int rc;
  763. #if USE_THE_EMMC
  764. blockstart = (offset / DEVESIZE(dev)) * DEVESIZE(dev);
  765. /* Offset inside a block */
  766. block_seek = offset - blockstart;
  767. #else
  768. blockstart = 0;
  769. /* Offset inside a block */
  770. block_seek = 0;
  771. #endif
  772. if (DEVTYPE(dev) == MTD_NANDFLASH) {
  773. /*
  774. * NAND: calculate which blocks we are reading. We have
  775. * to read one block at a time to skip bad blocks.
  776. */
  777. blocklen = DEVESIZE(dev);
  778. /* Limit to one block for the first read */
  779. if (readlen > blocklen - block_seek)
  780. readlen = blocklen - block_seek;
  781. } else {
  782. blocklen = 0;
  783. }
  784. /* This only runs once on NOR flash */
  785. while (processed < count) {
  786. rc = flash_bad_block(fd, DEVTYPE(dev), blockstart);
  787. if (rc < 0) /* block test failed */
  788. return -1;
  789. if (blockstart + block_seek + readlen > environment_end(dev)) {
  790. /* End of range is reached */
  791. fprintf(stderr, "Too few good blocks within range\n");
  792. return -1;
  793. }
  794. if (rc) { /* block is bad */
  795. blockstart += blocklen;
  796. continue;
  797. }
  798. /*
  799. * If a block is bad, we retry in the next block at the same
  800. * offset - see env/nand.c::writeenv()
  801. */
  802. lseek(fd, blockstart + block_seek, SEEK_SET);
  803. rc = read(fd, buf + processed, readlen);
  804. if (rc != readlen) {
  805. fprintf(stderr, "Read error on %s: %s\n",
  806. DEVNAME(dev), strerror(errno));
  807. return -1;
  808. }
  809. #ifdef DEBUG
  810. fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n",
  811. rc, (unsigned long long)blockstart + block_seek,
  812. DEVNAME(dev));
  813. #endif
  814. processed += readlen;
  815. readlen = min(blocklen, count - processed);
  816. block_seek = 0;
  817. blockstart += blocklen;
  818. }
  819. return processed;
  820. }
  821. /*
  822. * Write count bytes from begin of environment, but stay within
  823. * ENVSECTORS(dev) sectors of
  824. * DEVOFFSET (dev). Similar to the read case above, on NOR and dataflash we
  825. * erase and write the whole data at once.
  826. */
  827. static int flash_write_buf(int dev, int fd, void *buf, size_t count)
  828. {
  829. void *data;
  830. struct erase_info_user erase;
  831. size_t blocklen; /* length of NAND block / NOR erase sector */
  832. size_t erase_len; /* whole area that can be erased - may include
  833. bad blocks */
  834. size_t erasesize; /* erase / write length - one block on NAND,
  835. whole area on NOR */
  836. size_t processed = 0; /* progress counter */
  837. size_t write_total; /* total size to actually write - excluding
  838. bad blocks */
  839. off_t erase_offset; /* offset to the first erase block (aligned)
  840. below offset */
  841. off_t block_seek; /* offset inside the erase block to the start
  842. of the data */
  843. loff_t blockstart; /* running start of the current block -
  844. MEMGETBADBLOCK needs 64 bits */
  845. int rc;
  846. /*
  847. * For mtd devices only offset and size of the environment do matter
  848. */
  849. if (DEVTYPE(dev) == MTD_ABSENT) {
  850. blocklen = count;
  851. erase_len = blocklen;
  852. blockstart = DEVOFFSET(dev);
  853. block_seek = 0;
  854. write_total = blocklen;
  855. } else {
  856. blocklen = DEVESIZE(dev);
  857. erase_offset = DEVOFFSET(dev);
  858. /* Maximum area we may use */
  859. erase_len = environment_end(dev) - erase_offset;
  860. #if USE_THE_EMMC
  861. blockstart = erase_offset;
  862. /* Offset inside a block */
  863. block_seek = DEVOFFSET(dev) - erase_offset;
  864. #else
  865. blockstart = 0;
  866. block_seek = 0;
  867. #endif
  868. /*
  869. * Data size we actually write: from the start of the block
  870. * to the start of the data, then count bytes of data, and
  871. * to the end of the block
  872. */
  873. write_total = ((block_seek + count + blocklen - 1) /
  874. blocklen) * blocklen;
  875. }
  876. /*
  877. * Support data anywhere within erase sectors: read out the complete
  878. * area to be erased, replace the environment image, write the whole
  879. * block back again.
  880. */
  881. if (write_total > count) {
  882. data = malloc(erase_len);
  883. if (!data) {
  884. fprintf(stderr,
  885. "Cannot malloc %zu bytes: %s\n",
  886. erase_len, strerror(errno));
  887. return -1;
  888. }
  889. rc = flash_read_buf(dev, fd, data, write_total, erase_offset);
  890. if (write_total != rc)
  891. return -1;
  892. #ifdef DEBUG
  893. fprintf(stderr, "Preserving data ");
  894. if (block_seek != 0)
  895. fprintf(stderr, "0x%x - 0x%lx", 0, block_seek - 1);
  896. if (block_seek + count != write_total) {
  897. if (block_seek != 0)
  898. fprintf(stderr, " and ");
  899. fprintf(stderr, "0x%lx - 0x%lx",
  900. (unsigned long)block_seek + count,
  901. (unsigned long)write_total - 1);
  902. }
  903. fprintf(stderr, "\n");
  904. #endif
  905. /* Overwrite the old environment */
  906. memcpy(data + block_seek, buf, count);
  907. } else {
  908. /*
  909. * We get here, iff offset is block-aligned and count is a
  910. * multiple of blocklen - see write_total calculation above
  911. */
  912. data = buf;
  913. }
  914. if (DEVTYPE(dev) == MTD_NANDFLASH) {
  915. /*
  916. * NAND: calculate which blocks we are writing. We have
  917. * to write one block at a time to skip bad blocks.
  918. */
  919. erasesize = blocklen;
  920. } else {
  921. erasesize = erase_len;
  922. }
  923. erase.length = erasesize;
  924. /* This only runs once on NOR flash and SPI-dataflash */
  925. while (processed < write_total) {
  926. rc = flash_bad_block(fd, DEVTYPE(dev), blockstart);
  927. if (rc < 0) /* block test failed */
  928. return rc;
  929. if (blockstart + erasesize > environment_end(dev)) {
  930. fprintf(stderr, "End of range reached, aborting\n");
  931. return -1;
  932. }
  933. if (rc) { /* block is bad */
  934. blockstart += blocklen;
  935. continue;
  936. }
  937. if (DEVTYPE(dev) != MTD_ABSENT) {
  938. erase.start = blockstart;
  939. ioctl(fd, MEMUNLOCK, &erase);
  940. /* These do not need an explicit erase cycle */
  941. if (DEVTYPE(dev) != MTD_DATAFLASH)
  942. if (ioctl(fd, MEMERASE, &erase) != 0) {
  943. fprintf(stderr,
  944. "MTD erase error on %s: %s\n",
  945. DEVNAME(dev), strerror(errno));
  946. return -1;
  947. }
  948. }
  949. if (lseek(fd, blockstart, SEEK_SET) == -1) {
  950. fprintf(stderr,
  951. "Seek error on %s: %s\n",
  952. DEVNAME(dev), strerror(errno));
  953. return -1;
  954. }
  955. #ifdef DEBUG
  956. fprintf(stderr, "Write 0x%llx bytes at 0x%llx\n",
  957. (unsigned long long)erasesize,
  958. (unsigned long long)blockstart);
  959. #endif
  960. if (write(fd, data + processed, erasesize) != erasesize) {
  961. fprintf(stderr, "Write error on %s: %s\n",
  962. DEVNAME(dev), strerror(errno));
  963. return -1;
  964. }
  965. if (DEVTYPE(dev) != MTD_ABSENT)
  966. ioctl(fd, MEMLOCK, &erase);
  967. processed += erasesize;
  968. block_seek = 0;
  969. blockstart += erasesize;
  970. }
  971. if (write_total > count)
  972. free(data);
  973. return processed;
  974. }
  975. /*
  976. * Set obsolete flag at offset - NOR flash only
  977. */
  978. static int flash_flag_obsolete(int dev, int fd, off_t offset)
  979. {
  980. int rc;
  981. struct erase_info_user erase;
  982. erase.start = DEVOFFSET(dev);
  983. erase.length = DEVESIZE(dev);
  984. /* This relies on the fact, that obsolete_flag == 0 */
  985. rc = lseek(fd, offset, SEEK_SET);
  986. if (rc < 0) {
  987. fprintf(stderr, "Cannot seek to set the flag on %s\n",
  988. DEVNAME(dev));
  989. return rc;
  990. }
  991. ioctl(fd, MEMUNLOCK, &erase);
  992. rc = write(fd, &obsolete_flag, sizeof(obsolete_flag));
  993. ioctl(fd, MEMLOCK, &erase);
  994. if (rc < 0)
  995. perror("Could not set obsolete flag");
  996. return rc;
  997. }
  998. static int flash_write(int fd_current, int fd_target, int dev_target)
  999. {
  1000. int rc;
  1001. switch (environment.flag_scheme) {
  1002. case FLAG_NONE:
  1003. break;
  1004. case FLAG_INCREMENTAL:
  1005. (*environment.flags)++;
  1006. break;
  1007. case FLAG_BOOLEAN:
  1008. *environment.flags = active_flag;
  1009. break;
  1010. default:
  1011. fprintf(stderr, "Unimplemented flash scheme %u\n",
  1012. environment.flag_scheme);
  1013. return -1;
  1014. }
  1015. #ifdef DEBUG
  1016. fprintf(stderr, "Writing new environment at 0x%llx on %s\n",
  1017. DEVOFFSET(dev_target), DEVNAME(dev_target));
  1018. #endif
  1019. if (IS_UBI(dev_target)) {
  1020. if (ubi_update_start(fd_target, CUR_ENVSIZE) < 0)
  1021. return 0;
  1022. return ubi_write(fd_target, environment.image, CUR_ENVSIZE);
  1023. }
  1024. rc = flash_write_buf(dev_target, fd_target, environment.image,
  1025. CUR_ENVSIZE);
  1026. if (rc < 0)
  1027. return rc;
  1028. if (environment.flag_scheme == FLAG_BOOLEAN) {
  1029. /* Have to set obsolete flag */
  1030. off_t offset = DEVOFFSET(dev_current) +
  1031. offsetof(struct env_image_redundant, flags);
  1032. #ifdef DEBUG
  1033. fprintf(stderr,
  1034. "Setting obsolete flag in environment at 0x%llx on %s\n",
  1035. DEVOFFSET(dev_current), DEVNAME(dev_current));
  1036. #endif
  1037. flash_flag_obsolete(dev_current, fd_current, offset);
  1038. }
  1039. return 0;
  1040. }
  1041. static int flash_read(int fd)
  1042. {
  1043. int rc;
  1044. if (IS_UBI(dev_current)) {
  1045. DEVTYPE(dev_current) = MTD_ABSENT;
  1046. return ubi_read(fd, environment.image, CUR_ENVSIZE);
  1047. }
  1048. rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
  1049. DEVOFFSET(dev_current));
  1050. if (rc != CUR_ENVSIZE)
  1051. return -1;
  1052. return 0;
  1053. }
  1054. static int flash_open_tempfile(const char **dname, const char **target_temp)
  1055. {
  1056. char *dup_name = strdup(DEVNAME(dev_current));
  1057. char *temp_name = NULL;
  1058. int rc = -1;
  1059. if (!dup_name)
  1060. return -1;
  1061. *dname = dirname(dup_name);
  1062. if (!*dname)
  1063. goto err;
  1064. rc = asprintf(&temp_name, "%s/XXXXXX", *dname);
  1065. if (rc == -1)
  1066. goto err;
  1067. rc = mkstemp(temp_name);
  1068. if (rc == -1) {
  1069. /* fall back to in place write */
  1070. fprintf(stderr,
  1071. "Can't create %s: %s\n", temp_name, strerror(errno));
  1072. free(temp_name);
  1073. } else {
  1074. *target_temp = temp_name;
  1075. /* deliberately leak dup_name as dname /might/ point into
  1076. * it and we need it for our caller
  1077. */
  1078. dup_name = NULL;
  1079. }
  1080. err:
  1081. if (dup_name)
  1082. free(dup_name);
  1083. return rc;
  1084. }
  1085. static int flash_io_write(int fd_current)
  1086. {
  1087. int fd_target = -1, rc, dev_target;
  1088. const char *dname, *target_temp = NULL;
  1089. if (have_redund_env) {
  1090. /* switch to next partition for writing */
  1091. dev_target = !dev_current;
  1092. /* dev_target: fd_target, erase_target */
  1093. fd_target = open(DEVNAME(dev_target), O_RDWR);
  1094. if (fd_target < 0) {
  1095. fprintf(stderr,
  1096. "Can't open %s: %s\n",
  1097. DEVNAME(dev_target), strerror(errno));
  1098. rc = -1;
  1099. goto exit;
  1100. }
  1101. } else {
  1102. struct stat sb;
  1103. if (fstat(fd_current, &sb) == 0 && S_ISREG(sb.st_mode)) {
  1104. /* if any part of flash_open_tempfile() fails we fall
  1105. * back to in-place writes
  1106. */
  1107. fd_target = flash_open_tempfile(&dname, &target_temp);
  1108. }
  1109. dev_target = dev_current;
  1110. if (fd_target == -1)
  1111. fd_target = fd_current;
  1112. }
  1113. rc = flash_write(fd_current, fd_target, dev_target);
  1114. if (fsync(fd_current) && !(errno == EINVAL || errno == EROFS)) {
  1115. fprintf(stderr,
  1116. "fsync failed on %s: %s\n",
  1117. DEVNAME(dev_current), strerror(errno));
  1118. }
  1119. if (fd_current != fd_target) {
  1120. if (fsync(fd_target) &&
  1121. !(errno == EINVAL || errno == EROFS)) {
  1122. fprintf(stderr,
  1123. "fsync failed on %s: %s\n",
  1124. DEVNAME(dev_current), strerror(errno));
  1125. }
  1126. if (close(fd_target)) {
  1127. fprintf(stderr,
  1128. "I/O error on %s: %s\n",
  1129. DEVNAME(dev_target), strerror(errno));
  1130. rc = -1;
  1131. }
  1132. if (target_temp) {
  1133. int dir_fd;
  1134. dir_fd = open(dname, O_DIRECTORY | O_RDONLY);
  1135. if (dir_fd == -1)
  1136. fprintf(stderr,
  1137. "Can't open %s: %s\n",
  1138. dname, strerror(errno));
  1139. if (rename(target_temp, DEVNAME(dev_target))) {
  1140. fprintf(stderr,
  1141. "rename failed %s => %s: %s\n",
  1142. target_temp, DEVNAME(dev_target),
  1143. strerror(errno));
  1144. rc = -1;
  1145. }
  1146. if (dir_fd != -1 && fsync(dir_fd))
  1147. fprintf(stderr,
  1148. "fsync failed on %s: %s\n",
  1149. dname, strerror(errno));
  1150. if (dir_fd != -1 && close(dir_fd))
  1151. fprintf(stderr,
  1152. "I/O error on %s: %s\n",
  1153. dname, strerror(errno));
  1154. }
  1155. }
  1156. exit:
  1157. return rc;
  1158. }
  1159. static int flash_io(int mode)
  1160. {
  1161. int fd_current, rc;
  1162. /* dev_current: fd_current, erase_current */
  1163. fd_current = open(DEVNAME(dev_current), mode);
  1164. if (fd_current < 0) {
  1165. fprintf(stderr,
  1166. "Can't open %s: %s\n",
  1167. DEVNAME(dev_current), strerror(errno));
  1168. return -1;
  1169. }
  1170. if (mode == O_RDWR) {
  1171. rc = flash_io_write(fd_current);
  1172. } else {
  1173. rc = flash_read(fd_current);
  1174. }
  1175. if (close(fd_current)) {
  1176. fprintf(stderr,
  1177. "I/O error on %s: %s\n",
  1178. DEVNAME(dev_current), strerror(errno));
  1179. return -1;
  1180. }
  1181. return rc;
  1182. }
  1183. /*
  1184. * Prevent confusion if running from erased flash memory
  1185. */
  1186. int fw_env_open(struct env_opts *opts)
  1187. {
  1188. int crc0, crc0_ok;
  1189. unsigned char flag0;
  1190. void *addr0 = NULL;
  1191. int crc1, crc1_ok;
  1192. unsigned char flag1;
  1193. void *addr1 = NULL;
  1194. int ret;
  1195. struct env_image_single *single;
  1196. struct env_image_redundant *redundant;
  1197. if (!opts)
  1198. opts = &default_opts;
  1199. if (parse_config(opts)) /* should fill envdevices */
  1200. return -EINVAL;
  1201. addr0 = calloc(1, CUR_ENVSIZE);
  1202. if (addr0 == NULL) {
  1203. fprintf(stderr,
  1204. "Not enough memory for environment (%ld bytes)\n",
  1205. CUR_ENVSIZE);
  1206. ret = -ENOMEM;
  1207. goto open_cleanup;
  1208. }
  1209. /* read environment from FLASH to local buffer */
  1210. environment.image = addr0;
  1211. if (have_redund_env) {
  1212. redundant = addr0;
  1213. environment.crc = &redundant->crc;
  1214. environment.flags = &redundant->flags;
  1215. environment.data = redundant->data;
  1216. } else {
  1217. single = addr0;
  1218. environment.crc = &single->crc;
  1219. environment.flags = NULL;
  1220. environment.data = single->data;
  1221. }
  1222. dev_current = 0;
  1223. if (flash_io(O_RDONLY)) {
  1224. ret = -EIO;
  1225. goto open_cleanup;
  1226. }
  1227. crc0 = crc32(0, (uint8_t *)environment.data, ENV_SIZE);
  1228. crc0_ok = (crc0 == *environment.crc);
  1229. if (!have_redund_env) {
  1230. if (!crc0_ok) {
  1231. fprintf(stderr,
  1232. "Warning: Bad CRC, using default environment\n");
  1233. memcpy(environment.data, default_environment,
  1234. sizeof(default_environment));
  1235. }
  1236. } else {
  1237. flag0 = *environment.flags;
  1238. dev_current = 1;
  1239. addr1 = calloc(1, CUR_ENVSIZE);
  1240. if (addr1 == NULL) {
  1241. fprintf(stderr,
  1242. "Not enough memory for environment (%ld bytes)\n",
  1243. CUR_ENVSIZE);
  1244. ret = -ENOMEM;
  1245. goto open_cleanup;
  1246. }
  1247. redundant = addr1;
  1248. /*
  1249. * have to set environment.image for flash_read(), careful -
  1250. * other pointers in environment still point inside addr0
  1251. */
  1252. environment.image = addr1;
  1253. if (flash_io(O_RDONLY)) {
  1254. ret = -EIO;
  1255. goto open_cleanup;
  1256. }
  1257. /* Check flag scheme compatibility */
  1258. if (DEVTYPE(dev_current) == MTD_NORFLASH &&
  1259. DEVTYPE(!dev_current) == MTD_NORFLASH) {
  1260. environment.flag_scheme = FLAG_BOOLEAN;
  1261. } else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
  1262. DEVTYPE(!dev_current) == MTD_NANDFLASH) {
  1263. environment.flag_scheme = FLAG_INCREMENTAL;
  1264. } else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
  1265. DEVTYPE(!dev_current) == MTD_DATAFLASH) {
  1266. environment.flag_scheme = FLAG_BOOLEAN;
  1267. } else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
  1268. DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
  1269. environment.flag_scheme = FLAG_INCREMENTAL;
  1270. } else if (DEVTYPE(dev_current) == MTD_ABSENT &&
  1271. DEVTYPE(!dev_current) == MTD_ABSENT &&
  1272. IS_UBI(dev_current) == IS_UBI(!dev_current)) {
  1273. environment.flag_scheme = FLAG_INCREMENTAL;
  1274. } else {
  1275. fprintf(stderr, "Incompatible flash types!\n");
  1276. ret = -EINVAL;
  1277. goto open_cleanup;
  1278. }
  1279. crc1 = crc32(0, (uint8_t *)redundant->data, ENV_SIZE);
  1280. crc1_ok = (crc1 == redundant->crc);
  1281. flag1 = redundant->flags;
  1282. if (crc0_ok && !crc1_ok) {
  1283. dev_current = 0;
  1284. } else if (!crc0_ok && crc1_ok) {
  1285. dev_current = 1;
  1286. } else if (!crc0_ok && !crc1_ok) {
  1287. fprintf(stderr,
  1288. "Warning: Bad CRC, using default environment\n");
  1289. memcpy(environment.data, default_environment,
  1290. sizeof(default_environment));
  1291. dev_current = 0;
  1292. } else {
  1293. switch (environment.flag_scheme) {
  1294. case FLAG_BOOLEAN:
  1295. if (flag0 == active_flag &&
  1296. flag1 == obsolete_flag) {
  1297. dev_current = 0;
  1298. } else if (flag0 == obsolete_flag &&
  1299. flag1 == active_flag) {
  1300. dev_current = 1;
  1301. } else if (flag0 == flag1) {
  1302. dev_current = 0;
  1303. } else if (flag0 == 0xFF) {
  1304. dev_current = 0;
  1305. } else if (flag1 == 0xFF) {
  1306. dev_current = 1;
  1307. } else {
  1308. dev_current = 0;
  1309. }
  1310. break;
  1311. case FLAG_INCREMENTAL:
  1312. if (flag0 == 255 && flag1 == 0)
  1313. dev_current = 1;
  1314. else if ((flag1 == 255 && flag0 == 0) ||
  1315. flag0 >= flag1)
  1316. dev_current = 0;
  1317. else /* flag1 > flag0 */
  1318. dev_current = 1;
  1319. break;
  1320. default:
  1321. fprintf(stderr, "Unknown flag scheme %u\n",
  1322. environment.flag_scheme);
  1323. return -1;
  1324. }
  1325. }
  1326. /*
  1327. * If we are reading, we don't need the flag and the CRC any
  1328. * more, if we are writing, we will re-calculate CRC and update
  1329. * flags before writing out
  1330. */
  1331. if (dev_current) {
  1332. environment.image = addr1;
  1333. environment.crc = &redundant->crc;
  1334. environment.flags = &redundant->flags;
  1335. environment.data = redundant->data;
  1336. free(addr0);
  1337. } else {
  1338. environment.image = addr0;
  1339. /* Other pointers are already set */
  1340. free(addr1);
  1341. }
  1342. #ifdef DEBUG
  1343. fprintf(stderr, "Selected env in %s\n", DEVNAME(dev_current));
  1344. #endif
  1345. }
  1346. return 0;
  1347. open_cleanup:
  1348. if (addr0)
  1349. free(addr0);
  1350. if (addr1)
  1351. free(addr0);
  1352. return ret;
  1353. }
  1354. /*
  1355. * Simply free allocated buffer with environment
  1356. */
  1357. int fw_env_close(struct env_opts *opts)
  1358. {
  1359. if (environment.image)
  1360. free(environment.image);
  1361. environment.image = NULL;
  1362. return 0;
  1363. }
  1364. static int check_device_config(int dev)
  1365. {
  1366. struct stat st;
  1367. int32_t lnum = 0;
  1368. int fd, rc = 0;
  1369. /* Fills in IS_UBI(), converts DEVNAME() with ubi volume name */
  1370. ubi_check_dev(dev);
  1371. fd = open(DEVNAME(dev), O_RDONLY);
  1372. if (fd < 0) {
  1373. fprintf(stderr,
  1374. "Cannot open %s: %s\n", DEVNAME(dev), strerror(errno));
  1375. return -1;
  1376. }
  1377. rc = fstat(fd, &st);
  1378. if (rc < 0) {
  1379. fprintf(stderr, "Cannot stat the file %s\n", DEVNAME(dev));
  1380. goto err;
  1381. }
  1382. if (IS_UBI(dev)) {
  1383. rc = ioctl(fd, UBI_IOCEBISMAP, &lnum);
  1384. if (rc < 0) {
  1385. fprintf(stderr, "Cannot get UBI information for %s\n",
  1386. DEVNAME(dev));
  1387. goto err;
  1388. }
  1389. } else if (S_ISCHR(st.st_mode)) {
  1390. struct mtd_info_user mtdinfo;
  1391. rc = ioctl(fd, MEMGETINFO, &mtdinfo);
  1392. if (rc < 0) {
  1393. fprintf(stderr, "Cannot get MTD information for %s\n",
  1394. DEVNAME(dev));
  1395. goto err;
  1396. }
  1397. if (mtdinfo.type != MTD_NORFLASH &&
  1398. mtdinfo.type != MTD_NANDFLASH &&
  1399. mtdinfo.type != MTD_DATAFLASH &&
  1400. mtdinfo.type != MTD_UBIVOLUME) {
  1401. fprintf(stderr, "Unsupported flash type %u on %s\n",
  1402. mtdinfo.type, DEVNAME(dev));
  1403. goto err;
  1404. }
  1405. DEVTYPE(dev) = mtdinfo.type;
  1406. if (DEVESIZE(dev) == 0)
  1407. /* Assume the erase size is the same as the env-size */
  1408. DEVESIZE(dev) = ENVSIZE(dev);
  1409. } else {
  1410. uint64_t size;
  1411. DEVTYPE(dev) = MTD_ABSENT;
  1412. if (DEVESIZE(dev) == 0)
  1413. /* Assume the erase size to be 512 bytes */
  1414. DEVESIZE(dev) = 0x200;
  1415. /*
  1416. * Check for negative offsets, treat it as backwards offset
  1417. * from the end of the block device
  1418. */
  1419. if (DEVOFFSET(dev) < 0) {
  1420. rc = ioctl(fd, BLKGETSIZE64, &size);
  1421. if (rc < 0) {
  1422. fprintf(stderr,
  1423. "Could not get block device size on %s\n",
  1424. DEVNAME(dev));
  1425. goto err;
  1426. }
  1427. DEVOFFSET(dev) = DEVOFFSET(dev) + size;
  1428. #ifdef DEBUG
  1429. fprintf(stderr,
  1430. "Calculated device offset 0x%llx on %s\n",
  1431. DEVOFFSET(dev), DEVNAME(dev));
  1432. #endif
  1433. }
  1434. }
  1435. if (ENVSECTORS(dev) == 0)
  1436. /* Assume enough sectors to cover the environment */
  1437. ENVSECTORS(dev) = DIV_ROUND_UP(ENVSIZE(dev), DEVESIZE(dev));
  1438. if (DEVOFFSET(dev) % DEVESIZE(dev) != 0) {
  1439. fprintf(stderr,
  1440. "Environment does not start on (erase) block boundary\n");
  1441. errno = EINVAL;
  1442. return -1;
  1443. }
  1444. if (ENVSIZE(dev) > ENVSECTORS(dev) * DEVESIZE(dev)) {
  1445. fprintf(stderr,
  1446. "Environment does not fit into available sectors\n");
  1447. errno = EINVAL;
  1448. return -1;
  1449. }
  1450. err:
  1451. close(fd);
  1452. return rc;
  1453. }
  1454. static int parse_config(struct env_opts *opts)
  1455. {
  1456. int rc;
  1457. if (!opts)
  1458. opts = &default_opts;
  1459. #if defined(CONFIG_FILE)
  1460. /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */
  1461. if (get_config(opts->config_file)) {
  1462. fprintf(stderr, "Cannot parse config file '%s': %m\n",
  1463. opts->config_file);
  1464. return -1;
  1465. }
  1466. #else
  1467. DEVNAME(0) = DEVICE1_NAME;
  1468. DEVOFFSET(0) = DEVICE1_OFFSET;
  1469. ENVSIZE(0) = ENV1_SIZE;
  1470. /* Set defaults for DEVESIZE, ENVSECTORS later once we
  1471. * know DEVTYPE
  1472. */
  1473. #ifdef DEVICE1_ESIZE
  1474. DEVESIZE(0) = DEVICE1_ESIZE;
  1475. #endif
  1476. #ifdef DEVICE1_ENVSECTORS
  1477. ENVSECTORS(0) = DEVICE1_ENVSECTORS;
  1478. #endif
  1479. #ifdef HAVE_REDUND
  1480. DEVNAME(1) = DEVICE2_NAME;
  1481. DEVOFFSET(1) = DEVICE2_OFFSET;
  1482. ENVSIZE(1) = ENV2_SIZE;
  1483. /* Set defaults for DEVESIZE, ENVSECTORS later once we
  1484. * know DEVTYPE
  1485. */
  1486. #ifdef DEVICE2_ESIZE
  1487. DEVESIZE(1) = DEVICE2_ESIZE;
  1488. #endif
  1489. #ifdef DEVICE2_ENVSECTORS
  1490. ENVSECTORS(1) = DEVICE2_ENVSECTORS;
  1491. #endif
  1492. have_redund_env = 1;
  1493. #endif
  1494. #endif
  1495. rc = check_device_config(0);
  1496. if (rc < 0)
  1497. return rc;
  1498. if (have_redund_env) {
  1499. rc = check_device_config(1);
  1500. if (rc < 0)
  1501. return rc;
  1502. if (ENVSIZE(0) != ENVSIZE(1)) {
  1503. fprintf(stderr,
  1504. "Redundant environments have unequal size");
  1505. return -1;
  1506. }
  1507. }
  1508. usable_envsize = CUR_ENVSIZE - sizeof(uint32_t);
  1509. if (have_redund_env)
  1510. usable_envsize -= sizeof(char);
  1511. return 0;
  1512. }
  1513. #if defined(CONFIG_FILE)
  1514. static int get_config(char *fname)
  1515. {
  1516. FILE *fp;
  1517. int i = 0;
  1518. int rc;
  1519. char *line = NULL;
  1520. size_t linesize = 0;
  1521. char *devname;
  1522. fp = fopen(fname, "r");
  1523. if (fp == NULL)
  1524. return -1;
  1525. while (i < 2 && getline(&line, &linesize, fp) != -1) {
  1526. /* Skip comment strings */
  1527. if (line[0] == '#')
  1528. continue;
  1529. rc = sscanf(line, "%ms %lli %lx %lx %lx",
  1530. &devname,
  1531. &DEVOFFSET(i),
  1532. &ENVSIZE(i), &DEVESIZE(i), &ENVSECTORS(i));
  1533. if (rc < 3)
  1534. continue;
  1535. DEVNAME(i) = devname;
  1536. /* Set defaults for DEVESIZE, ENVSECTORS later once we
  1537. * know DEVTYPE
  1538. */
  1539. i++;
  1540. }
  1541. free(line);
  1542. fclose(fp);
  1543. have_redund_env = i - 1;
  1544. if (!i) { /* No valid entries found */
  1545. errno = EINVAL;
  1546. return -1;
  1547. } else
  1548. return 0;
  1549. }
  1550. #endif