1 /* 2 * (C) Copyright 2008 Semihalf 3 * 4 * (C) Copyright 2000-2006 5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26 #ifndef USE_HOSTCC 27 #include <common.h> 28 #include <watchdog.h> 29 30 #ifdef CONFIG_SHOW_BOOT_PROGRESS 31 #include <status_led.h> 32 #endif 33 34 #ifdef CONFIG_HAS_DATAFLASH 35 #include <dataflash.h> 36 #endif 37 38 #ifdef CONFIG_LOGBUFFER 39 #include <logbuff.h> 40 #endif 41 42 #include <rtc.h> 43 44 #include <environment.h> 45 #include <image.h> 46 47 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) 48 #include <libfdt.h> 49 #include <fdt_support.h> 50 #endif 51 52 #include <u-boot/md5.h> 53 #include <sha1.h> 54 #include <asm/io.h> 55 56 #ifdef CONFIG_CMD_BDI 57 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); 58 #endif 59 60 DECLARE_GLOBAL_DATA_PTR; 61 62 static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, 63 int verify); 64 #else 65 #include "mkimage.h" 66 #include <u-boot/md5.h> 67 #include <time.h> 68 #include <image.h> 69 #endif /* !USE_HOSTCC*/ 70 71 #include <u-boot/crc.h> 72 73 static const table_entry_t uimage_arch[] = { 74 { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, 75 { IH_ARCH_ALPHA, "alpha", "Alpha", }, 76 { IH_ARCH_ARM, "arm", "ARM", }, 77 { IH_ARCH_I386, "x86", "Intel x86", }, 78 { IH_ARCH_IA64, "ia64", "IA64", }, 79 { IH_ARCH_M68K, "m68k", "M68K", }, 80 { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, 81 { IH_ARCH_MIPS, "mips", "MIPS", }, 82 { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, 83 { IH_ARCH_NIOS2, "nios2", "NIOS II", }, 84 { IH_ARCH_PPC, "powerpc", "PowerPC", }, 85 { IH_ARCH_PPC, "ppc", "PowerPC", }, 86 { IH_ARCH_S390, "s390", "IBM S390", }, 87 { IH_ARCH_SH, "sh", "SuperH", }, 88 { IH_ARCH_SPARC, "sparc", "SPARC", }, 89 { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, 90 { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, 91 { IH_ARCH_AVR32, "avr32", "AVR32", }, 92 { IH_ARCH_NDS32, "nds32", "NDS32", }, 93 { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, 94 { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, 95 { -1, "", "", }, 96 }; 97 98 static const table_entry_t uimage_os[] = { 99 { IH_OS_INVALID, NULL, "Invalid OS", }, 100 { IH_OS_LINUX, "linux", "Linux", }, 101 #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) 102 { IH_OS_LYNXOS, "lynxos", "LynxOS", }, 103 #endif 104 { IH_OS_NETBSD, "netbsd", "NetBSD", }, 105 { IH_OS_OSE, "ose", "Enea OSE", }, 106 { IH_OS_PLAN9, "plan9", "Plan 9", }, 107 { IH_OS_RTEMS, "rtems", "RTEMS", }, 108 { IH_OS_U_BOOT, "u-boot", "U-Boot", }, 109 #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) 110 { IH_OS_QNX, "qnx", "QNX", }, 111 { IH_OS_VXWORKS, "vxworks", "VxWorks", }, 112 #endif 113 #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC) 114 { IH_OS_INTEGRITY,"integrity", "INTEGRITY", }, 115 #endif 116 #ifdef USE_HOSTCC 117 { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, 118 { IH_OS_DELL, "dell", "Dell", }, 119 { IH_OS_ESIX, "esix", "Esix", }, 120 { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, 121 { IH_OS_IRIX, "irix", "Irix", }, 122 { IH_OS_NCR, "ncr", "NCR", }, 123 { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, 124 { IH_OS_PSOS, "psos", "pSOS", }, 125 { IH_OS_SCO, "sco", "SCO", }, 126 { IH_OS_SOLARIS, "solaris", "Solaris", }, 127 { IH_OS_SVR4, "svr4", "SVR4", }, 128 #endif 129 { -1, "", "", }, 130 }; 131 132 static const table_entry_t uimage_type[] = { 133 { IH_TYPE_AISIMAGE, "aisimage", "Davinci AIS image",}, 134 { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, 135 { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, 136 { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, 137 { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, 138 { IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", }, 139 { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",}, 140 { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",}, 141 { IH_TYPE_INVALID, NULL, "Invalid Image", }, 142 { IH_TYPE_MULTI, "multi", "Multi-File Image", }, 143 { IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",}, 144 { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, 145 { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, 146 { IH_TYPE_SCRIPT, "script", "Script", }, 147 { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, 148 { IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",}, 149 { -1, "", "", }, 150 }; 151 152 static const table_entry_t uimage_comp[] = { 153 { IH_COMP_NONE, "none", "uncompressed", }, 154 { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, 155 { IH_COMP_GZIP, "gzip", "gzip compressed", }, 156 { IH_COMP_LZMA, "lzma", "lzma compressed", }, 157 { IH_COMP_LZO, "lzo", "lzo compressed", }, 158 { -1, "", "", }, 159 }; 160 161 /*****************************************************************************/ 162 /* Legacy format routines */ 163 /*****************************************************************************/ 164 int image_check_hcrc(const image_header_t *hdr) 165 { 166 ulong hcrc; 167 ulong len = image_get_header_size(); 168 image_header_t header; 169 170 /* Copy header so we can blank CRC field for re-calculation */ 171 memmove(&header, (char *)hdr, image_get_header_size()); 172 image_set_hcrc(&header, 0); 173 174 hcrc = crc32(0, (unsigned char *)&header, len); 175 176 return (hcrc == image_get_hcrc(hdr)); 177 } 178 179 int image_check_dcrc(const image_header_t *hdr) 180 { 181 ulong data = image_get_data(hdr); 182 ulong len = image_get_data_size(hdr); 183 ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32); 184 185 return (dcrc == image_get_dcrc(hdr)); 186 } 187 188 /** 189 * image_multi_count - get component (sub-image) count 190 * @hdr: pointer to the header of the multi component image 191 * 192 * image_multi_count() returns number of components in a multi 193 * component image. 194 * 195 * Note: no checking of the image type is done, caller must pass 196 * a valid multi component image. 197 * 198 * returns: 199 * number of components 200 */ 201 ulong image_multi_count(const image_header_t *hdr) 202 { 203 ulong i, count = 0; 204 uint32_t *size; 205 206 /* get start of the image payload, which in case of multi 207 * component images that points to a table of component sizes */ 208 size = (uint32_t *)image_get_data(hdr); 209 210 /* count non empty slots */ 211 for (i = 0; size[i]; ++i) 212 count++; 213 214 return count; 215 } 216 217 /** 218 * image_multi_getimg - get component data address and size 219 * @hdr: pointer to the header of the multi component image 220 * @idx: index of the requested component 221 * @data: pointer to a ulong variable, will hold component data address 222 * @len: pointer to a ulong variable, will hold component size 223 * 224 * image_multi_getimg() returns size and data address for the requested 225 * component in a multi component image. 226 * 227 * Note: no checking of the image type is done, caller must pass 228 * a valid multi component image. 229 * 230 * returns: 231 * data address and size of the component, if idx is valid 232 * 0 in data and len, if idx is out of range 233 */ 234 void image_multi_getimg(const image_header_t *hdr, ulong idx, 235 ulong *data, ulong *len) 236 { 237 int i; 238 uint32_t *size; 239 ulong offset, count, img_data; 240 241 /* get number of component */ 242 count = image_multi_count(hdr); 243 244 /* get start of the image payload, which in case of multi 245 * component images that points to a table of component sizes */ 246 size = (uint32_t *)image_get_data(hdr); 247 248 /* get address of the proper component data start, which means 249 * skipping sizes table (add 1 for last, null entry) */ 250 img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t); 251 252 if (idx < count) { 253 *len = uimage_to_cpu(size[idx]); 254 offset = 0; 255 256 /* go over all indices preceding requested component idx */ 257 for (i = 0; i < idx; i++) { 258 /* add up i-th component size, rounding up to 4 bytes */ 259 offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; 260 } 261 262 /* calculate idx-th component data address */ 263 *data = img_data + offset; 264 } else { 265 *len = 0; 266 *data = 0; 267 } 268 } 269 270 static void image_print_type(const image_header_t *hdr) 271 { 272 const char *os, *arch, *type, *comp; 273 274 os = genimg_get_os_name(image_get_os(hdr)); 275 arch = genimg_get_arch_name(image_get_arch(hdr)); 276 type = genimg_get_type_name(image_get_type(hdr)); 277 comp = genimg_get_comp_name(image_get_comp(hdr)); 278 279 printf("%s %s %s (%s)\n", arch, os, type, comp); 280 } 281 282 /** 283 * image_print_contents - prints out the contents of the legacy format image 284 * @ptr: pointer to the legacy format image header 285 * @p: pointer to prefix string 286 * 287 * image_print_contents() formats a multi line legacy image contents description. 288 * The routine prints out all header fields followed by the size/offset data 289 * for MULTI/SCRIPT images. 290 * 291 * returns: 292 * no returned results 293 */ 294 void image_print_contents(const void *ptr) 295 { 296 const image_header_t *hdr = (const image_header_t *)ptr; 297 const char *p; 298 299 p = IMAGE_INDENT_STRING; 300 printf("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name(hdr)); 301 if (IMAGE_ENABLE_TIMESTAMP) { 302 printf("%sCreated: ", p); 303 genimg_print_time((time_t)image_get_time(hdr)); 304 } 305 printf("%sImage Type: ", p); 306 image_print_type(hdr); 307 printf("%sData Size: ", p); 308 genimg_print_size(image_get_data_size(hdr)); 309 printf("%sLoad Address: %08x\n", p, image_get_load(hdr)); 310 printf("%sEntry Point: %08x\n", p, image_get_ep(hdr)); 311 312 if (image_check_type(hdr, IH_TYPE_MULTI) || 313 image_check_type(hdr, IH_TYPE_SCRIPT)) { 314 int i; 315 ulong data, len; 316 ulong count = image_multi_count(hdr); 317 318 printf("%sContents:\n", p); 319 for (i = 0; i < count; i++) { 320 image_multi_getimg(hdr, i, &data, &len); 321 322 printf("%s Image %d: ", p, i); 323 genimg_print_size(len); 324 325 if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) { 326 /* 327 * the user may need to know offsets 328 * if planning to do something with 329 * multiple files 330 */ 331 printf("%s Offset = 0x%08lx\n", p, data); 332 } 333 } 334 } 335 } 336 337 338 #ifndef USE_HOSTCC 339 /** 340 * image_get_ramdisk - get and verify ramdisk image 341 * @rd_addr: ramdisk image start address 342 * @arch: expected ramdisk architecture 343 * @verify: checksum verification flag 344 * 345 * image_get_ramdisk() returns a pointer to the verified ramdisk image 346 * header. Routine receives image start address and expected architecture 347 * flag. Verification done covers data and header integrity and os/type/arch 348 * fields checking. 349 * 350 * If dataflash support is enabled routine checks for dataflash addresses 351 * and handles required dataflash reads. 352 * 353 * returns: 354 * pointer to a ramdisk image header, if image was found and valid 355 * otherwise, return NULL 356 */ 357 static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, 358 int verify) 359 { 360 const image_header_t *rd_hdr = (const image_header_t *)rd_addr; 361 362 if (!image_check_magic(rd_hdr)) { 363 puts("Bad Magic Number\n"); 364 bootstage_error(BOOTSTAGE_ID_RD_MAGIC); 365 return NULL; 366 } 367 368 if (!image_check_hcrc(rd_hdr)) { 369 puts("Bad Header Checksum\n"); 370 bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM); 371 return NULL; 372 } 373 374 bootstage_mark(BOOTSTAGE_ID_RD_MAGIC); 375 image_print_contents(rd_hdr); 376 377 if (verify) { 378 puts(" Verifying Checksum ... "); 379 if (!image_check_dcrc(rd_hdr)) { 380 puts("Bad Data CRC\n"); 381 bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM); 382 return NULL; 383 } 384 puts("OK\n"); 385 } 386 387 bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM); 388 389 if (!image_check_os(rd_hdr, IH_OS_LINUX) || 390 !image_check_arch(rd_hdr, arch) || 391 !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) { 392 printf("No Linux %s Ramdisk Image\n", 393 genimg_get_arch_name(arch)); 394 bootstage_error(BOOTSTAGE_ID_RAMDISK); 395 return NULL; 396 } 397 398 return rd_hdr; 399 } 400 #endif /* !USE_HOSTCC */ 401 402 /*****************************************************************************/ 403 /* Shared dual-format routines */ 404 /*****************************************************************************/ 405 #ifndef USE_HOSTCC 406 ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ 407 ulong save_addr; /* Default Save Address */ 408 ulong save_size; /* Default Save Size (in bytes) */ 409 410 static int on_loadaddr(const char *name, const char *value, enum env_op op, 411 int flags) 412 { 413 switch (op) { 414 case env_op_create: 415 case env_op_overwrite: 416 load_addr = simple_strtoul(value, NULL, 16); 417 break; 418 default: 419 break; 420 } 421 422 return 0; 423 } 424 U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr); 425 426 ulong getenv_bootm_low(void) 427 { 428 char *s = getenv("bootm_low"); 429 if (s) { 430 ulong tmp = simple_strtoul(s, NULL, 16); 431 return tmp; 432 } 433 434 #if defined(CONFIG_SYS_SDRAM_BASE) 435 return CONFIG_SYS_SDRAM_BASE; 436 #elif defined(CONFIG_ARM) 437 return gd->bd->bi_dram[0].start; 438 #else 439 return 0; 440 #endif 441 } 442 443 phys_size_t getenv_bootm_size(void) 444 { 445 phys_size_t tmp; 446 char *s = getenv("bootm_size"); 447 if (s) { 448 tmp = (phys_size_t)simple_strtoull(s, NULL, 16); 449 return tmp; 450 } 451 s = getenv("bootm_low"); 452 if (s) 453 tmp = (phys_size_t)simple_strtoull(s, NULL, 16); 454 else 455 tmp = 0; 456 457 458 #if defined(CONFIG_ARM) 459 return gd->bd->bi_dram[0].size - tmp; 460 #else 461 return gd->bd->bi_memsize - tmp; 462 #endif 463 } 464 465 phys_size_t getenv_bootm_mapsize(void) 466 { 467 phys_size_t tmp; 468 char *s = getenv("bootm_mapsize"); 469 if (s) { 470 tmp = (phys_size_t)simple_strtoull(s, NULL, 16); 471 return tmp; 472 } 473 474 #if defined(CONFIG_SYS_BOOTMAPSZ) 475 return CONFIG_SYS_BOOTMAPSZ; 476 #else 477 return getenv_bootm_size(); 478 #endif 479 } 480 481 void memmove_wd(void *to, void *from, size_t len, ulong chunksz) 482 { 483 if (to == from) 484 return; 485 486 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 487 while (len > 0) { 488 size_t tail = (len > chunksz) ? chunksz : len; 489 WATCHDOG_RESET(); 490 memmove(to, from, tail); 491 to += tail; 492 from += tail; 493 len -= tail; 494 } 495 #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ 496 memmove(to, from, len); 497 #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ 498 } 499 #endif /* !USE_HOSTCC */ 500 501 void genimg_print_size(uint32_t size) 502 { 503 #ifndef USE_HOSTCC 504 printf("%d Bytes = ", size); 505 print_size(size, "\n"); 506 #else 507 printf("%d Bytes = %.2f kB = %.2f MB\n", 508 size, (double)size / 1.024e3, 509 (double)size / 1.048576e6); 510 #endif 511 } 512 513 #if IMAGE_ENABLE_TIMESTAMP 514 void genimg_print_time(time_t timestamp) 515 { 516 #ifndef USE_HOSTCC 517 struct rtc_time tm; 518 519 to_tm(timestamp, &tm); 520 printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", 521 tm.tm_year, tm.tm_mon, tm.tm_mday, 522 tm.tm_hour, tm.tm_min, tm.tm_sec); 523 #else 524 printf("%s", ctime(×tamp)); 525 #endif 526 } 527 #endif 528 529 /** 530 * get_table_entry_name - translate entry id to long name 531 * @table: pointer to a translation table for entries of a specific type 532 * @msg: message to be returned when translation fails 533 * @id: entry id to be translated 534 * 535 * get_table_entry_name() will go over translation table trying to find 536 * entry that matches given id. If matching entry is found, its long 537 * name is returned to the caller. 538 * 539 * returns: 540 * long entry name if translation succeeds 541 * msg otherwise 542 */ 543 char *get_table_entry_name(const table_entry_t *table, char *msg, int id) 544 { 545 for (; table->id >= 0; ++table) { 546 if (table->id == id) 547 #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) 548 return table->lname; 549 #else 550 return table->lname + gd->reloc_off; 551 #endif 552 } 553 return (msg); 554 } 555 556 const char *genimg_get_os_name(uint8_t os) 557 { 558 return (get_table_entry_name(uimage_os, "Unknown OS", os)); 559 } 560 561 const char *genimg_get_arch_name(uint8_t arch) 562 { 563 return (get_table_entry_name(uimage_arch, "Unknown Architecture", 564 arch)); 565 } 566 567 const char *genimg_get_type_name(uint8_t type) 568 { 569 return (get_table_entry_name(uimage_type, "Unknown Image", type)); 570 } 571 572 const char *genimg_get_comp_name(uint8_t comp) 573 { 574 return (get_table_entry_name(uimage_comp, "Unknown Compression", 575 comp)); 576 } 577 578 /** 579 * get_table_entry_id - translate short entry name to id 580 * @table: pointer to a translation table for entries of a specific type 581 * @table_name: to be used in case of error 582 * @name: entry short name to be translated 583 * 584 * get_table_entry_id() will go over translation table trying to find 585 * entry that matches given short name. If matching entry is found, 586 * its id returned to the caller. 587 * 588 * returns: 589 * entry id if translation succeeds 590 * -1 otherwise 591 */ 592 int get_table_entry_id(const table_entry_t *table, 593 const char *table_name, const char *name) 594 { 595 const table_entry_t *t; 596 #ifdef USE_HOSTCC 597 int first = 1; 598 599 for (t = table; t->id >= 0; ++t) { 600 if (t->sname && strcasecmp(t->sname, name) == 0) 601 return(t->id); 602 } 603 604 fprintf(stderr, "\nInvalid %s Type - valid names are", table_name); 605 for (t = table; t->id >= 0; ++t) { 606 if (t->sname == NULL) 607 continue; 608 fprintf(stderr, "%c %s", (first) ? ':' : ',', t->sname); 609 first = 0; 610 } 611 fprintf(stderr, "\n"); 612 #else 613 for (t = table; t->id >= 0; ++t) { 614 #ifdef CONFIG_NEEDS_MANUAL_RELOC 615 if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0) 616 #else 617 if (t->sname && strcmp(t->sname, name) == 0) 618 #endif 619 return (t->id); 620 } 621 debug("Invalid %s Type: %s\n", table_name, name); 622 #endif /* USE_HOSTCC */ 623 return (-1); 624 } 625 626 int genimg_get_os_id(const char *name) 627 { 628 return (get_table_entry_id(uimage_os, "OS", name)); 629 } 630 631 int genimg_get_arch_id(const char *name) 632 { 633 return (get_table_entry_id(uimage_arch, "CPU", name)); 634 } 635 636 int genimg_get_type_id(const char *name) 637 { 638 return (get_table_entry_id(uimage_type, "Image", name)); 639 } 640 641 int genimg_get_comp_id(const char *name) 642 { 643 return (get_table_entry_id(uimage_comp, "Compression", name)); 644 } 645 646 #ifndef USE_HOSTCC 647 /** 648 * genimg_get_format - get image format type 649 * @img_addr: image start address 650 * 651 * genimg_get_format() checks whether provided address points to a valid 652 * legacy or FIT image. 653 * 654 * New uImage format and FDT blob are based on a libfdt. FDT blob 655 * may be passed directly or embedded in a FIT image. In both situations 656 * genimg_get_format() must be able to dectect libfdt header. 657 * 658 * returns: 659 * image format type or IMAGE_FORMAT_INVALID if no image is present 660 */ 661 int genimg_get_format(const void *img_addr) 662 { 663 ulong format = IMAGE_FORMAT_INVALID; 664 const image_header_t *hdr; 665 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) 666 char *fit_hdr; 667 #endif 668 669 hdr = (const image_header_t *)img_addr; 670 if (image_check_magic(hdr)) 671 format = IMAGE_FORMAT_LEGACY; 672 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) 673 else { 674 fit_hdr = (char *)img_addr; 675 if (fdt_check_header(fit_hdr) == 0) 676 format = IMAGE_FORMAT_FIT; 677 } 678 #endif 679 680 return format; 681 } 682 683 /** 684 * genimg_get_image - get image from special storage (if necessary) 685 * @img_addr: image start address 686 * 687 * genimg_get_image() checks if provided image start adddress is located 688 * in a dataflash storage. If so, image is moved to a system RAM memory. 689 * 690 * returns: 691 * image start address after possible relocation from special storage 692 */ 693 ulong genimg_get_image(ulong img_addr) 694 { 695 ulong ram_addr = img_addr; 696 697 #ifdef CONFIG_HAS_DATAFLASH 698 ulong h_size, d_size; 699 700 if (addr_dataflash(img_addr)) { 701 void *buf; 702 703 /* ger RAM address */ 704 ram_addr = CONFIG_SYS_LOAD_ADDR; 705 706 /* get header size */ 707 h_size = image_get_header_size(); 708 #if defined(CONFIG_FIT) 709 if (sizeof(struct fdt_header) > h_size) 710 h_size = sizeof(struct fdt_header); 711 #endif 712 713 /* read in header */ 714 debug(" Reading image header from dataflash address " 715 "%08lx to RAM address %08lx\n", img_addr, ram_addr); 716 717 buf = map_sysmem(ram_addr, 0); 718 read_dataflash(img_addr, h_size, buf); 719 720 /* get data size */ 721 switch (genimg_get_format(buf)) { 722 case IMAGE_FORMAT_LEGACY: 723 d_size = image_get_data_size(buf); 724 debug(" Legacy format image found at 0x%08lx, " 725 "size 0x%08lx\n", 726 ram_addr, d_size); 727 break; 728 #if defined(CONFIG_FIT) 729 case IMAGE_FORMAT_FIT: 730 d_size = fit_get_size(buf) - h_size; 731 debug(" FIT/FDT format image found at 0x%08lx, " 732 "size 0x%08lx\n", 733 ram_addr, d_size); 734 break; 735 #endif 736 default: 737 printf(" No valid image found at 0x%08lx\n", 738 img_addr); 739 return ram_addr; 740 } 741 742 /* read in image data */ 743 debug(" Reading image remaining data from dataflash address " 744 "%08lx to RAM address %08lx\n", img_addr + h_size, 745 ram_addr + h_size); 746 747 read_dataflash(img_addr + h_size, d_size, 748 (char *)(buf + h_size)); 749 750 } 751 #endif /* CONFIG_HAS_DATAFLASH */ 752 753 return ram_addr; 754 } 755 756 /** 757 * fit_has_config - check if there is a valid FIT configuration 758 * @images: pointer to the bootm command headers structure 759 * 760 * fit_has_config() checks if there is a FIT configuration in use 761 * (if FTI support is present). 762 * 763 * returns: 764 * 0, no FIT support or no configuration found 765 * 1, configuration found 766 */ 767 int genimg_has_config(bootm_headers_t *images) 768 { 769 #if defined(CONFIG_FIT) 770 if (images->fit_uname_cfg) 771 return 1; 772 #endif 773 return 0; 774 } 775 776 /** 777 * boot_get_ramdisk - main ramdisk handling routine 778 * @argc: command argument count 779 * @argv: command argument list 780 * @images: pointer to the bootm images structure 781 * @arch: expected ramdisk architecture 782 * @rd_start: pointer to a ulong variable, will hold ramdisk start address 783 * @rd_end: pointer to a ulong variable, will hold ramdisk end 784 * 785 * boot_get_ramdisk() is responsible for finding a valid ramdisk image. 786 * Curently supported are the following ramdisk sources: 787 * - multicomponent kernel/ramdisk image, 788 * - commandline provided address of decicated ramdisk image. 789 * 790 * returns: 791 * 0, if ramdisk image was found and valid, or skiped 792 * rd_start and rd_end are set to ramdisk start/end addresses if 793 * ramdisk image is found and valid 794 * 795 * 1, if ramdisk image is found but corrupted, or invalid 796 * rd_start and rd_end are set to 0 if no ramdisk exists 797 */ 798 int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, 799 uint8_t arch, ulong *rd_start, ulong *rd_end) 800 { 801 ulong rd_addr, rd_load; 802 ulong rd_data, rd_len; 803 const image_header_t *rd_hdr; 804 void *buf; 805 #ifdef CONFIG_SUPPORT_RAW_INITRD 806 char *end; 807 #endif 808 #if defined(CONFIG_FIT) 809 void *fit_hdr; 810 const char *fit_uname_config = NULL; 811 const char *fit_uname_ramdisk = NULL; 812 ulong default_addr; 813 int rd_noffset; 814 int cfg_noffset; 815 const void *data; 816 size_t size; 817 #endif 818 819 *rd_start = 0; 820 *rd_end = 0; 821 822 /* 823 * Look for a '-' which indicates to ignore the 824 * ramdisk argument 825 */ 826 if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { 827 debug("## Skipping init Ramdisk\n"); 828 rd_len = rd_data = 0; 829 } else if (argc >= 3 || genimg_has_config(images)) { 830 #if defined(CONFIG_FIT) 831 if (argc >= 3) { 832 /* 833 * If the init ramdisk comes from the FIT image and 834 * the FIT image address is omitted in the command 835 * line argument, try to use os FIT image address or 836 * default load address. 837 */ 838 if (images->fit_uname_os) 839 default_addr = (ulong)images->fit_hdr_os; 840 else 841 default_addr = load_addr; 842 843 if (fit_parse_conf(argv[2], default_addr, 844 &rd_addr, &fit_uname_config)) { 845 debug("* ramdisk: config '%s' from image at " 846 "0x%08lx\n", 847 fit_uname_config, rd_addr); 848 } else if (fit_parse_subimage(argv[2], default_addr, 849 &rd_addr, &fit_uname_ramdisk)) { 850 debug("* ramdisk: subimage '%s' from image at " 851 "0x%08lx\n", 852 fit_uname_ramdisk, rd_addr); 853 } else 854 #endif 855 { 856 rd_addr = simple_strtoul(argv[2], NULL, 16); 857 debug("* ramdisk: cmdline image address = " 858 "0x%08lx\n", 859 rd_addr); 860 } 861 #if defined(CONFIG_FIT) 862 } else { 863 /* use FIT configuration provided in first bootm 864 * command argument 865 */ 866 rd_addr = map_to_sysmem(images->fit_hdr_os); 867 fit_uname_config = images->fit_uname_cfg; 868 debug("* ramdisk: using config '%s' from image " 869 "at 0x%08lx\n", 870 fit_uname_config, rd_addr); 871 872 /* 873 * Check whether configuration has ramdisk defined, 874 * if not, don't try to use it, quit silently. 875 */ 876 fit_hdr = images->fit_hdr_os; 877 cfg_noffset = fit_conf_get_node(fit_hdr, 878 fit_uname_config); 879 if (cfg_noffset < 0) { 880 debug("* ramdisk: no such config\n"); 881 return 1; 882 } 883 884 rd_noffset = fit_conf_get_ramdisk_node(fit_hdr, 885 cfg_noffset); 886 if (rd_noffset < 0) { 887 debug("* ramdisk: no ramdisk in config\n"); 888 return 0; 889 } 890 } 891 #endif 892 893 /* copy from dataflash if needed */ 894 rd_addr = genimg_get_image(rd_addr); 895 896 /* 897 * Check if there is an initrd image at the 898 * address provided in the second bootm argument 899 * check image type, for FIT images get FIT node. 900 */ 901 buf = map_sysmem(rd_addr, 0); 902 switch (genimg_get_format(buf)) { 903 case IMAGE_FORMAT_LEGACY: 904 printf("## Loading init Ramdisk from Legacy " 905 "Image at %08lx ...\n", rd_addr); 906 907 bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); 908 rd_hdr = image_get_ramdisk(rd_addr, arch, 909 images->verify); 910 911 if (rd_hdr == NULL) 912 return 1; 913 914 rd_data = image_get_data(rd_hdr); 915 rd_len = image_get_data_size(rd_hdr); 916 rd_load = image_get_load(rd_hdr); 917 break; 918 #if defined(CONFIG_FIT) 919 case IMAGE_FORMAT_FIT: 920 fit_hdr = buf; 921 printf("## Loading init Ramdisk from FIT " 922 "Image at %08lx ...\n", rd_addr); 923 924 bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT); 925 if (!fit_check_format(fit_hdr)) { 926 puts("Bad FIT ramdisk image format!\n"); 927 bootstage_error( 928 BOOTSTAGE_ID_FIT_RD_FORMAT); 929 return 1; 930 } 931 bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK); 932 933 if (!fit_uname_ramdisk) { 934 /* 935 * no ramdisk image node unit name, try to get config 936 * node first. If config unit node name is NULL 937 * fit_conf_get_node() will try to find default config node 938 */ 939 bootstage_mark( 940 BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME); 941 cfg_noffset = fit_conf_get_node(fit_hdr, 942 fit_uname_config); 943 if (cfg_noffset < 0) { 944 puts("Could not find configuration " 945 "node\n"); 946 bootstage_error( 947 BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME); 948 return 1; 949 } 950 fit_uname_config = fdt_get_name(fit_hdr, 951 cfg_noffset, NULL); 952 printf(" Using '%s' configuration\n", 953 fit_uname_config); 954 955 rd_noffset = fit_conf_get_ramdisk_node(fit_hdr, 956 cfg_noffset); 957 fit_uname_ramdisk = fit_get_name(fit_hdr, 958 rd_noffset, NULL); 959 } else { 960 /* get ramdisk component image node offset */ 961 bootstage_mark( 962 BOOTSTAGE_ID_FIT_RD_UNIT_NAME); 963 rd_noffset = fit_image_get_node(fit_hdr, 964 fit_uname_ramdisk); 965 } 966 if (rd_noffset < 0) { 967 puts("Could not find subimage node\n"); 968 bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE); 969 return 1; 970 } 971 972 printf(" Trying '%s' ramdisk subimage\n", 973 fit_uname_ramdisk); 974 975 bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK); 976 if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch, 977 images->verify)) 978 return 1; 979 980 /* get ramdisk image data address and length */ 981 if (fit_image_get_data(fit_hdr, rd_noffset, &data, 982 &size)) { 983 puts("Could not find ramdisk subimage data!\n"); 984 bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA); 985 return 1; 986 } 987 bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK); 988 989 rd_data = (ulong)data; 990 rd_len = size; 991 992 if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) { 993 puts("Can't get ramdisk subimage load " 994 "address!\n"); 995 bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD); 996 return 1; 997 } 998 bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD); 999 1000 images->fit_hdr_rd = fit_hdr; 1001 images->fit_uname_rd = fit_uname_ramdisk; 1002 images->fit_noffset_rd = rd_noffset; 1003 break; 1004 #endif 1005 default: 1006 #ifdef CONFIG_SUPPORT_RAW_INITRD 1007 if (argc >= 3 && (end = strchr(argv[2], ':'))) { 1008 rd_len = simple_strtoul(++end, NULL, 16); 1009 rd_data = rd_addr; 1010 } else 1011 #endif 1012 { 1013 puts("Wrong Ramdisk Image Format\n"); 1014 rd_data = rd_len = rd_load = 0; 1015 return 1; 1016 } 1017 } 1018 } else if (images->legacy_hdr_valid && 1019 image_check_type(&images->legacy_hdr_os_copy, 1020 IH_TYPE_MULTI)) { 1021 1022 /* 1023 * Now check if we have a legacy mult-component image, 1024 * get second entry data start address and len. 1025 */ 1026 bootstage_mark(BOOTSTAGE_ID_RAMDISK); 1027 printf("## Loading init Ramdisk from multi component " 1028 "Legacy Image at %08lx ...\n", 1029 (ulong)images->legacy_hdr_os); 1030 1031 image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len); 1032 } else { 1033 /* 1034 * no initrd image 1035 */ 1036 bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK); 1037 rd_len = rd_data = 0; 1038 } 1039 1040 if (!rd_data) { 1041 debug("## No init Ramdisk\n"); 1042 } else { 1043 *rd_start = rd_data; 1044 *rd_end = rd_data + rd_len; 1045 } 1046 debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", 1047 *rd_start, *rd_end); 1048 1049 return 0; 1050 } 1051 1052 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 1053 /** 1054 * boot_ramdisk_high - relocate init ramdisk 1055 * @lmb: pointer to lmb handle, will be used for memory mgmt 1056 * @rd_data: ramdisk data start address 1057 * @rd_len: ramdisk data length 1058 * @initrd_start: pointer to a ulong variable, will hold final init ramdisk 1059 * start address (after possible relocation) 1060 * @initrd_end: pointer to a ulong variable, will hold final init ramdisk 1061 * end address (after possible relocation) 1062 * 1063 * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement 1064 * variable and if requested ramdisk data is moved to a specified location. 1065 * 1066 * Initrd_start and initrd_end are set to final (after relocation) ramdisk 1067 * start/end addresses if ramdisk image start and len were provided, 1068 * otherwise set initrd_start and initrd_end set to zeros. 1069 * 1070 * returns: 1071 * 0 - success 1072 * -1 - failure 1073 */ 1074 int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, 1075 ulong *initrd_start, ulong *initrd_end) 1076 { 1077 char *s; 1078 ulong initrd_high; 1079 int initrd_copy_to_ram = 1; 1080 1081 if ((s = getenv("initrd_high")) != NULL) { 1082 /* a value of "no" or a similar string will act like 0, 1083 * turning the "load high" feature off. This is intentional. 1084 */ 1085 initrd_high = simple_strtoul(s, NULL, 16); 1086 if (initrd_high == ~0) 1087 initrd_copy_to_ram = 0; 1088 } else { 1089 /* not set, no restrictions to load high */ 1090 initrd_high = ~0; 1091 } 1092 1093 1094 #ifdef CONFIG_LOGBUFFER 1095 /* Prevent initrd from overwriting logbuffer */ 1096 lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE); 1097 #endif 1098 1099 debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n", 1100 initrd_high, initrd_copy_to_ram); 1101 1102 if (rd_data) { 1103 if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ 1104 debug(" in-place initrd\n"); 1105 *initrd_start = rd_data; 1106 *initrd_end = rd_data + rd_len; 1107 lmb_reserve(lmb, rd_data, rd_len); 1108 } else { 1109 if (initrd_high) 1110 *initrd_start = (ulong)lmb_alloc_base(lmb, 1111 rd_len, 0x1000, initrd_high); 1112 else 1113 *initrd_start = (ulong)lmb_alloc(lmb, rd_len, 1114 0x1000); 1115 1116 if (*initrd_start == 0) { 1117 puts("ramdisk - allocation error\n"); 1118 goto error; 1119 } 1120 bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK); 1121 1122 *initrd_end = *initrd_start + rd_len; 1123 printf(" Loading Ramdisk to %08lx, end %08lx ... ", 1124 *initrd_start, *initrd_end); 1125 1126 memmove_wd((void *)*initrd_start, 1127 (void *)rd_data, rd_len, CHUNKSZ); 1128 1129 #ifdef CONFIG_MP 1130 /* 1131 * Ensure the image is flushed to memory to handle 1132 * AMP boot scenarios in which we might not be 1133 * HW cache coherent 1134 */ 1135 flush_cache((unsigned long)*initrd_start, rd_len); 1136 #endif 1137 puts("OK\n"); 1138 } 1139 } else { 1140 *initrd_start = 0; 1141 *initrd_end = 0; 1142 } 1143 debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", 1144 *initrd_start, *initrd_end); 1145 1146 return 0; 1147 1148 error: 1149 return -1; 1150 } 1151 #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ 1152 1153 #ifdef CONFIG_OF_LIBFDT 1154 static void fdt_error(const char *msg) 1155 { 1156 puts("ERROR: "); 1157 puts(msg); 1158 puts(" - must RESET the board to recover.\n"); 1159 } 1160 1161 static const image_header_t *image_get_fdt(ulong fdt_addr) 1162 { 1163 const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); 1164 1165 image_print_contents(fdt_hdr); 1166 1167 puts(" Verifying Checksum ... "); 1168 if (!image_check_hcrc(fdt_hdr)) { 1169 fdt_error("fdt header checksum invalid"); 1170 return NULL; 1171 } 1172 1173 if (!image_check_dcrc(fdt_hdr)) { 1174 fdt_error("fdt checksum invalid"); 1175 return NULL; 1176 } 1177 puts("OK\n"); 1178 1179 if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) { 1180 fdt_error("uImage is not a fdt"); 1181 return NULL; 1182 } 1183 if (image_get_comp(fdt_hdr) != IH_COMP_NONE) { 1184 fdt_error("uImage is compressed"); 1185 return NULL; 1186 } 1187 if (fdt_check_header((char *)image_get_data(fdt_hdr)) != 0) { 1188 fdt_error("uImage data is not a fdt"); 1189 return NULL; 1190 } 1191 return fdt_hdr; 1192 } 1193 1194 /** 1195 * fit_check_fdt - verify FIT format FDT subimage 1196 * @fit_hdr: pointer to the FIT header 1197 * fdt_noffset: FDT subimage node offset within FIT image 1198 * @verify: data CRC verification flag 1199 * 1200 * fit_check_fdt() verifies integrity of the FDT subimage and from 1201 * specified FIT image. 1202 * 1203 * returns: 1204 * 1, on success 1205 * 0, on failure 1206 */ 1207 #if defined(CONFIG_FIT) 1208 static int fit_check_fdt(const void *fit, int fdt_noffset, int verify) 1209 { 1210 fit_image_print(fit, fdt_noffset, " "); 1211 1212 if (verify) { 1213 puts(" Verifying Hash Integrity ... "); 1214 if (!fit_image_verify(fit, fdt_noffset)) { 1215 fdt_error("Bad Data Hash"); 1216 return 0; 1217 } 1218 puts("OK\n"); 1219 } 1220 1221 if (!fit_image_check_type(fit, fdt_noffset, IH_TYPE_FLATDT)) { 1222 fdt_error("Not a FDT image"); 1223 return 0; 1224 } 1225 1226 if (!fit_image_check_comp(fit, fdt_noffset, IH_COMP_NONE)) { 1227 fdt_error("FDT image is compressed"); 1228 return 0; 1229 } 1230 1231 return 1; 1232 } 1233 #endif /* CONFIG_FIT */ 1234 1235 #ifndef CONFIG_SYS_FDT_PAD 1236 #define CONFIG_SYS_FDT_PAD 0x3000 1237 #endif 1238 1239 #if defined(CONFIG_OF_LIBFDT) 1240 /** 1241 * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable 1242 * @lmb: pointer to lmb handle, will be used for memory mgmt 1243 * @fdt_blob: pointer to fdt blob base address 1244 * 1245 * Adds the memreserve regions in the dtb to the lmb block. Adding the 1246 * memreserve regions prevents u-boot from using them to store the initrd 1247 * or the fdt blob. 1248 */ 1249 void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) 1250 { 1251 uint64_t addr, size; 1252 int i, total; 1253 1254 if (fdt_check_header(fdt_blob) != 0) 1255 return; 1256 1257 total = fdt_num_mem_rsv(fdt_blob); 1258 for (i = 0; i < total; i++) { 1259 if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) 1260 continue; 1261 printf(" reserving fdt memory region: addr=%llx size=%llx\n", 1262 (unsigned long long)addr, (unsigned long long)size); 1263 lmb_reserve(lmb, addr, size); 1264 } 1265 } 1266 1267 /** 1268 * boot_relocate_fdt - relocate flat device tree 1269 * @lmb: pointer to lmb handle, will be used for memory mgmt 1270 * @of_flat_tree: pointer to a char* variable, will hold fdt start address 1271 * @of_size: pointer to a ulong variable, will hold fdt length 1272 * 1273 * boot_relocate_fdt() allocates a region of memory within the bootmap and 1274 * relocates the of_flat_tree into that region, even if the fdt is already in 1275 * the bootmap. It also expands the size of the fdt by CONFIG_SYS_FDT_PAD 1276 * bytes. 1277 * 1278 * of_flat_tree and of_size are set to final (after relocation) values 1279 * 1280 * returns: 1281 * 0 - success 1282 * 1 - failure 1283 */ 1284 int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) 1285 { 1286 void *fdt_blob = *of_flat_tree; 1287 void *of_start = NULL; 1288 char *fdt_high; 1289 ulong of_len = 0; 1290 int err; 1291 int disable_relocation = 0; 1292 1293 /* nothing to do */ 1294 if (*of_size == 0) 1295 return 0; 1296 1297 if (fdt_check_header(fdt_blob) != 0) { 1298 fdt_error("image is not a fdt"); 1299 goto error; 1300 } 1301 1302 /* position on a 4K boundary before the alloc_current */ 1303 /* Pad the FDT by a specified amount */ 1304 of_len = *of_size + CONFIG_SYS_FDT_PAD; 1305 1306 /* If fdt_high is set use it to select the relocation address */ 1307 fdt_high = getenv("fdt_high"); 1308 if (fdt_high) { 1309 void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16); 1310 1311 if (((ulong) desired_addr) == ~0UL) { 1312 /* All ones means use fdt in place */ 1313 of_start = fdt_blob; 1314 lmb_reserve(lmb, (ulong)of_start, of_len); 1315 disable_relocation = 1; 1316 } else if (desired_addr) { 1317 of_start = 1318 (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, 1319 (ulong)desired_addr); 1320 if (of_start == NULL) { 1321 puts("Failed using fdt_high value for Device Tree"); 1322 goto error; 1323 } 1324 } else { 1325 of_start = 1326 (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000); 1327 } 1328 } else { 1329 of_start = 1330 (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, 1331 getenv_bootm_mapsize() 1332 + getenv_bootm_low()); 1333 } 1334 1335 if (of_start == NULL) { 1336 puts("device tree - allocation error\n"); 1337 goto error; 1338 } 1339 1340 if (disable_relocation) { 1341 /* We assume there is space after the existing fdt to use for padding */ 1342 fdt_set_totalsize(of_start, of_len); 1343 printf(" Using Device Tree in place at %p, end %p\n", 1344 of_start, of_start + of_len - 1); 1345 } else { 1346 debug("## device tree at %p ... %p (len=%ld [0x%lX])\n", 1347 fdt_blob, fdt_blob + *of_size - 1, of_len, of_len); 1348 1349 printf(" Loading Device Tree to %p, end %p ... ", 1350 of_start, of_start + of_len - 1); 1351 1352 err = fdt_open_into(fdt_blob, of_start, of_len); 1353 if (err != 0) { 1354 fdt_error("fdt move failed"); 1355 goto error; 1356 } 1357 puts("OK\n"); 1358 } 1359 1360 *of_flat_tree = of_start; 1361 *of_size = of_len; 1362 1363 set_working_fdt_addr(*of_flat_tree); 1364 return 0; 1365 1366 error: 1367 return 1; 1368 } 1369 #endif /* CONFIG_OF_LIBFDT */ 1370 1371 /** 1372 * boot_get_fdt - main fdt handling routine 1373 * @argc: command argument count 1374 * @argv: command argument list 1375 * @images: pointer to the bootm images structure 1376 * @of_flat_tree: pointer to a char* variable, will hold fdt start address 1377 * @of_size: pointer to a ulong variable, will hold fdt length 1378 * 1379 * boot_get_fdt() is responsible for finding a valid flat device tree image. 1380 * Curently supported are the following ramdisk sources: 1381 * - multicomponent kernel/ramdisk image, 1382 * - commandline provided address of decicated ramdisk image. 1383 * 1384 * returns: 1385 * 0, if fdt image was found and valid, or skipped 1386 * of_flat_tree and of_size are set to fdt start address and length if 1387 * fdt image is found and valid 1388 * 1389 * 1, if fdt image is found but corrupted 1390 * of_flat_tree and of_size are set to 0 if no fdt exists 1391 */ 1392 int boot_get_fdt(int flag, int argc, char * const argv[], 1393 bootm_headers_t *images, char **of_flat_tree, ulong *of_size) 1394 { 1395 const image_header_t *fdt_hdr; 1396 ulong fdt_addr; 1397 char *fdt_blob = NULL; 1398 ulong image_start, image_data, image_end; 1399 ulong load_start, load_end; 1400 void *buf; 1401 #if defined(CONFIG_FIT) 1402 void *fit_hdr; 1403 const char *fit_uname_config = NULL; 1404 const char *fit_uname_fdt = NULL; 1405 ulong default_addr; 1406 int cfg_noffset; 1407 int fdt_noffset; 1408 const void *data; 1409 size_t size; 1410 #endif 1411 1412 *of_flat_tree = NULL; 1413 *of_size = 0; 1414 1415 if (argc > 3 || genimg_has_config(images)) { 1416 #if defined(CONFIG_FIT) 1417 if (argc > 3) { 1418 /* 1419 * If the FDT blob comes from the FIT image and the 1420 * FIT image address is omitted in the command line 1421 * argument, try to use ramdisk or os FIT image 1422 * address or default load address. 1423 */ 1424 if (images->fit_uname_rd) 1425 default_addr = (ulong)images->fit_hdr_rd; 1426 else if (images->fit_uname_os) 1427 default_addr = (ulong)images->fit_hdr_os; 1428 else 1429 default_addr = load_addr; 1430 1431 if (fit_parse_conf(argv[3], default_addr, 1432 &fdt_addr, &fit_uname_config)) { 1433 debug("* fdt: config '%s' from image at " 1434 "0x%08lx\n", 1435 fit_uname_config, fdt_addr); 1436 } else if (fit_parse_subimage(argv[3], default_addr, 1437 &fdt_addr, &fit_uname_fdt)) { 1438 debug("* fdt: subimage '%s' from image at " 1439 "0x%08lx\n", 1440 fit_uname_fdt, fdt_addr); 1441 } else 1442 #endif 1443 { 1444 fdt_addr = simple_strtoul(argv[3], NULL, 16); 1445 debug("* fdt: cmdline image address = " 1446 "0x%08lx\n", 1447 fdt_addr); 1448 } 1449 #if defined(CONFIG_FIT) 1450 } else { 1451 /* use FIT configuration provided in first bootm 1452 * command argument 1453 */ 1454 fdt_addr = map_to_sysmem(images->fit_hdr_os); 1455 fit_uname_config = images->fit_uname_cfg; 1456 debug("* fdt: using config '%s' from image " 1457 "at 0x%08lx\n", 1458 fit_uname_config, fdt_addr); 1459 1460 /* 1461 * Check whether configuration has FDT blob defined, 1462 * if not quit silently. 1463 */ 1464 fit_hdr = images->fit_hdr_os; 1465 cfg_noffset = fit_conf_get_node(fit_hdr, 1466 fit_uname_config); 1467 if (cfg_noffset < 0) { 1468 debug("* fdt: no such config\n"); 1469 return 0; 1470 } 1471 1472 fdt_noffset = fit_conf_get_fdt_node(fit_hdr, 1473 cfg_noffset); 1474 if (fdt_noffset < 0) { 1475 debug("* fdt: no fdt in config\n"); 1476 return 0; 1477 } 1478 } 1479 #endif 1480 1481 debug("## Checking for 'FDT'/'FDT Image' at %08lx\n", 1482 fdt_addr); 1483 1484 /* copy from dataflash if needed */ 1485 fdt_addr = genimg_get_image(fdt_addr); 1486 1487 /* 1488 * Check if there is an FDT image at the 1489 * address provided in the second bootm argument 1490 * check image type, for FIT images get a FIT node. 1491 */ 1492 buf = map_sysmem(fdt_addr, 0); 1493 switch (genimg_get_format(buf)) { 1494 case IMAGE_FORMAT_LEGACY: 1495 /* verify fdt_addr points to a valid image header */ 1496 printf("## Flattened Device Tree from Legacy Image " 1497 "at %08lx\n", 1498 fdt_addr); 1499 fdt_hdr = image_get_fdt(fdt_addr); 1500 if (!fdt_hdr) 1501 goto error; 1502 1503 /* 1504 * move image data to the load address, 1505 * make sure we don't overwrite initial image 1506 */ 1507 image_start = (ulong)fdt_hdr; 1508 image_data = (ulong)image_get_data(fdt_hdr); 1509 image_end = image_get_image_end(fdt_hdr); 1510 1511 load_start = image_get_load(fdt_hdr); 1512 load_end = load_start + image_get_data_size(fdt_hdr); 1513 1514 if (load_start == image_start || 1515 load_start == image_data) { 1516 fdt_blob = (char *)image_data; 1517 break; 1518 } 1519 1520 if ((load_start < image_end) && (load_end > image_start)) { 1521 fdt_error("fdt overwritten"); 1522 goto error; 1523 } 1524 1525 debug(" Loading FDT from 0x%08lx to 0x%08lx\n", 1526 image_data, load_start); 1527 1528 memmove((void *)load_start, 1529 (void *)image_data, 1530 image_get_data_size(fdt_hdr)); 1531 1532 fdt_blob = (char *)load_start; 1533 break; 1534 case IMAGE_FORMAT_FIT: 1535 /* 1536 * This case will catch both: new uImage format 1537 * (libfdt based) and raw FDT blob (also libfdt 1538 * based). 1539 */ 1540 #if defined(CONFIG_FIT) 1541 /* check FDT blob vs FIT blob */ 1542 if (fit_check_format(buf)) { 1543 /* 1544 * FIT image 1545 */ 1546 fit_hdr = buf; 1547 printf("## Flattened Device Tree from FIT " 1548 "Image at %08lx\n", 1549 fdt_addr); 1550 1551 if (!fit_uname_fdt) { 1552 /* 1553 * no FDT blob image node unit name, 1554 * try to get config node first. If 1555 * config unit node name is NULL 1556 * fit_conf_get_node() will try to 1557 * find default config node 1558 */ 1559 cfg_noffset = fit_conf_get_node(fit_hdr, 1560 fit_uname_config); 1561 1562 if (cfg_noffset < 0) { 1563 fdt_error("Could not find " 1564 "configuration " 1565 "node\n"); 1566 goto error; 1567 } 1568 1569 fit_uname_config = fdt_get_name(fit_hdr, 1570 cfg_noffset, NULL); 1571 printf(" Using '%s' configuration\n", 1572 fit_uname_config); 1573 1574 fdt_noffset = fit_conf_get_fdt_node( 1575 fit_hdr, 1576 cfg_noffset); 1577 fit_uname_fdt = fit_get_name(fit_hdr, 1578 fdt_noffset, NULL); 1579 } else { 1580 /* get FDT component image node offset */ 1581 fdt_noffset = fit_image_get_node( 1582 fit_hdr, 1583 fit_uname_fdt); 1584 } 1585 if (fdt_noffset < 0) { 1586 fdt_error("Could not find subimage " 1587 "node\n"); 1588 goto error; 1589 } 1590 1591 printf(" Trying '%s' FDT blob subimage\n", 1592 fit_uname_fdt); 1593 1594 if (!fit_check_fdt(fit_hdr, fdt_noffset, 1595 images->verify)) 1596 goto error; 1597 1598 /* get ramdisk image data address and length */ 1599 if (fit_image_get_data(fit_hdr, fdt_noffset, 1600 &data, &size)) { 1601 fdt_error("Could not find FDT " 1602 "subimage data"); 1603 goto error; 1604 } 1605 1606 /* verift that image data is a proper FDT blob */ 1607 if (fdt_check_header((char *)data) != 0) { 1608 fdt_error("Subimage data is not a FTD"); 1609 goto error; 1610 } 1611 1612 /* 1613 * move image data to the load address, 1614 * make sure we don't overwrite initial image 1615 */ 1616 image_start = (ulong)fit_hdr; 1617 image_end = fit_get_end(fit_hdr); 1618 1619 if (fit_image_get_load(fit_hdr, fdt_noffset, 1620 &load_start) == 0) { 1621 load_end = load_start + size; 1622 1623 if ((load_start < image_end) && 1624 (load_end > image_start)) { 1625 fdt_error("FDT overwritten"); 1626 goto error; 1627 } 1628 1629 printf(" Loading FDT from 0x%08lx " 1630 "to 0x%08lx\n", 1631 (ulong)data, 1632 load_start); 1633 1634 memmove((void *)load_start, 1635 (void *)data, size); 1636 1637 fdt_blob = (char *)load_start; 1638 } else { 1639 fdt_blob = (char *)data; 1640 } 1641 1642 images->fit_hdr_fdt = fit_hdr; 1643 images->fit_uname_fdt = fit_uname_fdt; 1644 images->fit_noffset_fdt = fdt_noffset; 1645 break; 1646 } else 1647 #endif 1648 { 1649 /* 1650 * FDT blob 1651 */ 1652 fdt_blob = buf; 1653 debug("* fdt: raw FDT blob\n"); 1654 printf("## Flattened Device Tree blob at %08lx\n", 1655 (long)fdt_addr); 1656 } 1657 break; 1658 default: 1659 puts("ERROR: Did not find a cmdline Flattened Device " 1660 "Tree\n"); 1661 goto error; 1662 } 1663 1664 printf(" Booting using the fdt blob at 0x%p\n", fdt_blob); 1665 1666 } else if (images->legacy_hdr_valid && 1667 image_check_type(&images->legacy_hdr_os_copy, 1668 IH_TYPE_MULTI)) { 1669 1670 ulong fdt_data, fdt_len; 1671 1672 /* 1673 * Now check if we have a legacy multi-component image, 1674 * get second entry data start address and len. 1675 */ 1676 printf("## Flattened Device Tree from multi " 1677 "component Image at %08lX\n", 1678 (ulong)images->legacy_hdr_os); 1679 1680 image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data, 1681 &fdt_len); 1682 if (fdt_len) { 1683 1684 fdt_blob = (char *)fdt_data; 1685 printf(" Booting using the fdt at 0x%p\n", fdt_blob); 1686 1687 if (fdt_check_header(fdt_blob) != 0) { 1688 fdt_error("image is not a fdt"); 1689 goto error; 1690 } 1691 1692 if (fdt_totalsize(fdt_blob) != fdt_len) { 1693 fdt_error("fdt size != image size"); 1694 goto error; 1695 } 1696 } else { 1697 debug("## No Flattened Device Tree\n"); 1698 return 0; 1699 } 1700 } else { 1701 debug("## No Flattened Device Tree\n"); 1702 return 0; 1703 } 1704 1705 *of_flat_tree = fdt_blob; 1706 *of_size = fdt_totalsize(fdt_blob); 1707 debug(" of_flat_tree at 0x%08lx size 0x%08lx\n", 1708 (ulong)*of_flat_tree, *of_size); 1709 1710 return 0; 1711 1712 error: 1713 *of_flat_tree = NULL; 1714 *of_size = 0; 1715 return 1; 1716 } 1717 #endif /* CONFIG_OF_LIBFDT */ 1718 1719 #ifdef CONFIG_SYS_BOOT_GET_CMDLINE 1720 /** 1721 * boot_get_cmdline - allocate and initialize kernel cmdline 1722 * @lmb: pointer to lmb handle, will be used for memory mgmt 1723 * @cmd_start: pointer to a ulong variable, will hold cmdline start 1724 * @cmd_end: pointer to a ulong variable, will hold cmdline end 1725 * 1726 * boot_get_cmdline() allocates space for kernel command line below 1727 * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt 1728 * variable is present its contents is copied to allocated kernel 1729 * command line. 1730 * 1731 * returns: 1732 * 0 - success 1733 * -1 - failure 1734 */ 1735 int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) 1736 { 1737 char *cmdline; 1738 char *s; 1739 1740 cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, 1741 getenv_bootm_mapsize() + getenv_bootm_low()); 1742 1743 if (cmdline == NULL) 1744 return -1; 1745 1746 if ((s = getenv("bootargs")) == NULL) 1747 s = ""; 1748 1749 strcpy(cmdline, s); 1750 1751 *cmd_start = (ulong) & cmdline[0]; 1752 *cmd_end = *cmd_start + strlen(cmdline); 1753 1754 debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); 1755 1756 return 0; 1757 } 1758 #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ 1759 1760 #ifdef CONFIG_SYS_BOOT_GET_KBD 1761 /** 1762 * boot_get_kbd - allocate and initialize kernel copy of board info 1763 * @lmb: pointer to lmb handle, will be used for memory mgmt 1764 * @kbd: double pointer to board info data 1765 * 1766 * boot_get_kbd() allocates space for kernel copy of board info data below 1767 * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized 1768 * with the current u-boot board info data. 1769 * 1770 * returns: 1771 * 0 - success 1772 * -1 - failure 1773 */ 1774 int boot_get_kbd(struct lmb *lmb, bd_t **kbd) 1775 { 1776 *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, 1777 getenv_bootm_mapsize() + getenv_bootm_low()); 1778 if (*kbd == NULL) 1779 return -1; 1780 1781 **kbd = *(gd->bd); 1782 1783 debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); 1784 1785 #if defined(DEBUG) && defined(CONFIG_CMD_BDI) 1786 do_bdinfo(NULL, 0, 0, NULL); 1787 #endif 1788 1789 return 0; 1790 } 1791 #endif /* CONFIG_SYS_BOOT_GET_KBD */ 1792 #endif /* !USE_HOSTCC */ 1793