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