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 #define DEBUG 27 28 #ifndef USE_HOSTCC 29 #include <common.h> 30 #include <watchdog.h> 31 32 #ifdef CONFIG_SHOW_BOOT_PROGRESS 33 #include <status_led.h> 34 #endif 35 36 #ifdef CONFIG_HAS_DATAFLASH 37 #include <dataflash.h> 38 #endif 39 40 #ifdef CONFIG_LOGBUFFER 41 #include <logbuff.h> 42 #endif 43 44 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) 45 #include <rtc.h> 46 #endif 47 48 #if defined(CONFIG_FIT) 49 #include <fdt.h> 50 #include <libfdt.h> 51 #include <fdt_support.h> 52 #endif 53 54 #ifdef CONFIG_CMD_BDI 55 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); 56 #endif 57 58 DECLARE_GLOBAL_DATA_PTR; 59 60 static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, 61 int argc, char *argv[], 62 ulong rd_addr, uint8_t arch, int verify); 63 #else 64 #include "mkimage.h" 65 #endif /* USE_HOSTCC*/ 66 67 #include <image.h> 68 69 unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); 70 71 int image_check_hcrc (image_header_t *hdr) 72 { 73 ulong hcrc; 74 ulong len = image_get_header_size (); 75 image_header_t header; 76 77 /* Copy header so we can blank CRC field for re-calculation */ 78 memmove (&header, (char *)hdr, image_get_header_size ()); 79 image_set_hcrc (&header, 0); 80 81 hcrc = crc32 (0, (unsigned char *)&header, len); 82 83 return (hcrc == image_get_hcrc (hdr)); 84 } 85 86 int image_check_dcrc (image_header_t *hdr) 87 { 88 ulong data = image_get_data (hdr); 89 ulong len = image_get_data_size (hdr); 90 ulong dcrc = crc32 (0, (unsigned char *)data, len); 91 92 return (dcrc == image_get_dcrc (hdr)); 93 } 94 95 #ifndef USE_HOSTCC 96 int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) 97 { 98 ulong dcrc = 0; 99 ulong len = image_get_data_size (hdr); 100 ulong data = image_get_data (hdr); 101 102 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 103 ulong cdata = data; 104 ulong edata = cdata + len; 105 106 while (cdata < edata) { 107 ulong chunk = edata - cdata; 108 109 if (chunk > chunksz) 110 chunk = chunksz; 111 dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk); 112 cdata += chunk; 113 114 WATCHDOG_RESET (); 115 } 116 #else 117 dcrc = crc32 (0, (unsigned char *)data, len); 118 #endif 119 120 return (dcrc == image_get_dcrc (hdr)); 121 } 122 123 int getenv_verify (void) 124 { 125 char *s = getenv ("verify"); 126 return (s && (*s == 'n')) ? 0 : 1; 127 } 128 129 int getenv_autostart (void) 130 { 131 char *s = getenv ("autostart"); 132 return (s && (*s == 'n')) ? 0 : 1; 133 } 134 135 void memmove_wd (void *to, void *from, size_t len, ulong chunksz) 136 { 137 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 138 while (len > 0) { 139 size_t tail = (len > chunksz) ? chunksz : len; 140 WATCHDOG_RESET (); 141 memmove (to, from, tail); 142 to += tail; 143 from += tail; 144 len -= tail; 145 } 146 #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ 147 memmove (to, from, len); 148 #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ 149 } 150 #endif /* USE_HOSTCC */ 151 152 /** 153 * image_multi_count - get component (sub-image) count 154 * @hdr: pointer to the header of the multi component image 155 * 156 * image_multi_count() returns number of components in a multi 157 * component image. 158 * 159 * Note: no checking of the image type is done, caller must pass 160 * a valid multi component image. 161 * 162 * returns: 163 * number of components 164 */ 165 ulong image_multi_count (image_header_t *hdr) 166 { 167 ulong i, count = 0; 168 ulong *size; 169 170 /* get start of the image payload, which in case of multi 171 * component images that points to a table of component sizes */ 172 size = (ulong *)image_get_data (hdr); 173 174 /* count non empty slots */ 175 for (i = 0; size[i]; ++i) 176 count++; 177 178 return count; 179 } 180 181 /** 182 * image_multi_getimg - get component data address and size 183 * @hdr: pointer to the header of the multi component image 184 * @idx: index of the requested component 185 * @data: pointer to a ulong variable, will hold component data address 186 * @len: pointer to a ulong variable, will hold component size 187 * 188 * image_multi_getimg() returns size and data address for the requested 189 * component in a multi component image. 190 * 191 * Note: no checking of the image type is done, caller must pass 192 * a valid multi component image. 193 * 194 * returns: 195 * data address and size of the component, if idx is valid 196 * 0 in data and len, if idx is out of range 197 */ 198 void image_multi_getimg (image_header_t *hdr, ulong idx, 199 ulong *data, ulong *len) 200 { 201 int i; 202 ulong *size; 203 ulong offset, tail, count, img_data; 204 205 /* get number of component */ 206 count = image_multi_count (hdr); 207 208 /* get start of the image payload, which in case of multi 209 * component images that points to a table of component sizes */ 210 size = (ulong *)image_get_data (hdr); 211 212 /* get address of the proper component data start, which means 213 * skipping sizes table (add 1 for last, null entry) */ 214 img_data = image_get_data (hdr) + (count + 1) * sizeof (ulong); 215 216 if (idx < count) { 217 *len = size[idx]; 218 offset = 0; 219 tail = 0; 220 221 /* go over all indices preceding requested component idx */ 222 for (i = 0; i < idx; i++) { 223 /* add up i-th component size */ 224 offset += size[i]; 225 226 /* add up alignment for i-th component */ 227 tail += (4 - size[i] % 4); 228 } 229 230 /* calculate idx-th component data address */ 231 *data = img_data + offset + tail; 232 } else { 233 *len = 0; 234 *data = 0; 235 } 236 } 237 238 #ifndef USE_HOSTCC 239 const char* image_get_os_name (uint8_t os) 240 { 241 const char *name; 242 243 switch (os) { 244 case IH_OS_INVALID: name = "Invalid OS"; break; 245 case IH_OS_NETBSD: name = "NetBSD"; break; 246 case IH_OS_LINUX: name = "Linux"; break; 247 case IH_OS_VXWORKS: name = "VxWorks"; break; 248 case IH_OS_QNX: name = "QNX"; break; 249 case IH_OS_U_BOOT: name = "U-Boot"; break; 250 case IH_OS_RTEMS: name = "RTEMS"; break; 251 #ifdef CONFIG_ARTOS 252 case IH_OS_ARTOS: name = "ARTOS"; break; 253 #endif 254 #ifdef CONFIG_LYNXKDI 255 case IH_OS_LYNXOS: name = "LynxOS"; break; 256 #endif 257 default: name = "Unknown OS"; break; 258 } 259 260 return name; 261 } 262 263 const char* image_get_arch_name (uint8_t arch) 264 { 265 const char *name; 266 267 switch (arch) { 268 case IH_ARCH_INVALID: name = "Invalid Architecture"; break; 269 case IH_ARCH_ALPHA: name = "Alpha"; break; 270 case IH_ARCH_ARM: name = "ARM"; break; 271 case IH_ARCH_AVR32: name = "AVR32"; break; 272 case IH_ARCH_BLACKFIN: name = "Blackfin"; break; 273 case IH_ARCH_I386: name = "Intel x86"; break; 274 case IH_ARCH_IA64: name = "IA64"; break; 275 case IH_ARCH_M68K: name = "M68K"; break; 276 case IH_ARCH_MICROBLAZE:name = "Microblaze"; break; 277 case IH_ARCH_MIPS64: name = "MIPS 64 Bit"; break; 278 case IH_ARCH_MIPS: name = "MIPS"; break; 279 case IH_ARCH_NIOS2: name = "Nios-II"; break; 280 case IH_ARCH_NIOS: name = "Nios"; break; 281 case IH_ARCH_PPC: name = "PowerPC"; break; 282 case IH_ARCH_S390: name = "IBM S390"; break; 283 case IH_ARCH_SH: name = "SuperH"; break; 284 case IH_ARCH_SPARC64: name = "SPARC 64 Bit"; break; 285 case IH_ARCH_SPARC: name = "SPARC"; break; 286 default: name = "Unknown Architecture"; break; 287 } 288 289 return name; 290 } 291 292 const char* image_get_type_name (uint8_t type) 293 { 294 const char *name; 295 296 switch (type) { 297 case IH_TYPE_INVALID: name = "Invalid Image"; break; 298 case IH_TYPE_STANDALONE:name = "Standalone Program"; break; 299 case IH_TYPE_KERNEL: name = "Kernel Image"; break; 300 case IH_TYPE_RAMDISK: name = "RAMDisk Image"; break; 301 case IH_TYPE_MULTI: name = "Multi-File Image"; break; 302 case IH_TYPE_FIRMWARE: name = "Firmware"; break; 303 case IH_TYPE_SCRIPT: name = "Script"; break; 304 case IH_TYPE_FLATDT: name = "Flat Device Tree"; break; 305 default: name = "Unknown Image"; break; 306 } 307 308 return name; 309 } 310 311 const char* image_get_comp_name (uint8_t comp) 312 { 313 const char *name; 314 315 switch (comp) { 316 case IH_COMP_NONE: name = "uncompressed"; break; 317 case IH_COMP_GZIP: name = "gzip compressed"; break; 318 case IH_COMP_BZIP2: name = "bzip2 compressed"; break; 319 default: name = "unknown compression"; break; 320 } 321 322 return name; 323 } 324 325 static void image_print_type (image_header_t *hdr) 326 { 327 const char *os, *arch, *type, *comp; 328 329 os = image_get_os_name (image_get_os (hdr)); 330 arch = image_get_arch_name (image_get_arch (hdr)); 331 type = image_get_type_name (image_get_type (hdr)); 332 comp = image_get_comp_name (image_get_comp (hdr)); 333 334 printf ("%s %s %s (%s)", arch, os, type, comp); 335 } 336 337 void image_print_contents (image_header_t *hdr) 338 { 339 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) 340 time_t timestamp = (time_t)image_get_time (hdr); 341 struct rtc_time tm; 342 #endif 343 344 printf (" Image Name: %.*s\n", IH_NMLEN, image_get_name (hdr)); 345 346 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) 347 to_tm (timestamp, &tm); 348 printf (" Created: %4d-%02d-%02d %2d:%02d:%02d UTC\n", 349 tm.tm_year, tm.tm_mon, tm.tm_mday, 350 tm.tm_hour, tm.tm_min, tm.tm_sec); 351 #endif 352 puts (" Image Type: "); 353 image_print_type (hdr); 354 355 printf ("\n Data Size: %d Bytes = ", image_get_data_size (hdr)); 356 print_size (image_get_data_size (hdr), "\n"); 357 printf (" Load Address: %08x\n" 358 " Entry Point: %08x\n", 359 image_get_load (hdr), image_get_ep (hdr)); 360 361 if (image_check_type (hdr, IH_TYPE_MULTI)) { 362 int i; 363 ulong data, len; 364 ulong count = image_multi_count (hdr); 365 366 puts (" Contents:\n"); 367 for (i = 0; i < count; i++) { 368 image_multi_getimg (hdr, i, &data, &len); 369 printf (" Image %d: %8ld Bytes = ", i, len); 370 print_size (len, "\n"); 371 } 372 } 373 } 374 375 /** 376 * gen_image_get_format - get image format type 377 * @img_addr: image start address 378 * 379 * gen_image_get_format() checks whether provided address points to a valid 380 * legacy or FIT image. 381 * 382 * New uImage format and FDT blob are based on a libfdt. FDT blob 383 * may be passed directly or embedded in a FIT image. In both situations 384 * gen_image_get_format() must be able to dectect libfdt header. 385 * 386 * returns: 387 * image format type or IMAGE_FORMAT_INVALID if no image is present 388 */ 389 int gen_image_get_format (void *img_addr) 390 { 391 ulong format = IMAGE_FORMAT_INVALID; 392 image_header_t *hdr; 393 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) 394 char *fit_hdr; 395 #endif 396 397 hdr = (image_header_t *)img_addr; 398 if (image_check_magic(hdr)) 399 format = IMAGE_FORMAT_LEGACY; 400 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) 401 else { 402 fit_hdr = (char *)img_addr; 403 if (fdt_check_header (fit_hdr) == 0) 404 format = IMAGE_FORMAT_FIT; 405 } 406 #endif 407 408 return format; 409 } 410 411 /** 412 * gen_get_image - get image from special storage (if necessary) 413 * @img_addr: image start address 414 * 415 * gen_get_image() checks if provided image start adddress is located 416 * in a dataflash storage. If so, image is moved to a system RAM memory. 417 * 418 * returns: 419 * image start address after possible relocation from special storage 420 */ 421 ulong gen_get_image (ulong img_addr) 422 { 423 ulong ram_addr = img_addr; 424 425 #ifdef CONFIG_HAS_DATAFLASH 426 ulong h_size, d_size; 427 428 if (addr_dataflash (img_addr)){ 429 /* ger RAM address */ 430 ram_addr = CFG_LOAD_ADDR; 431 432 /* get header size */ 433 h_size = image_get_header_size (); 434 #if defined(CONFIG_FIT) 435 if (sizeof(struct fdt_header) > h_size) 436 h_size = sizeof(struct fdt_header); 437 #endif 438 439 /* read in header */ 440 debug (" Reading image header from dataflash address " 441 "%08lx to RAM address %08lx\n", img_addr, ram_addr); 442 443 read_dataflash (img_addr, h_size, (char *)ram_addr); 444 445 /* get data size */ 446 switch (gen_image_get_format ((void *)ram_addr)) { 447 case IMAGE_FORMAT_LEGACY: 448 d_size = image_get_data_size ((image_header_t *)ram_addr); 449 debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", 450 ram_addr, d_size); 451 break; 452 #if defined(CONFIG_FIT) 453 case IMAGE_FORMAT_FIT: 454 d_size = fdt_totalsize((void *)ram_addr) - h_size; 455 debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", 456 ram_addr, d_size); 457 break; 458 #endif 459 default: 460 printf (" No valid image found at 0x%08lx\n", img_addr); 461 return ram_addr; 462 } 463 464 /* read in image data */ 465 debug (" Reading image remaining data from dataflash address " 466 "%08lx to RAM address %08lx\n", img_addr + h_size, 467 ram_addr + h_size); 468 469 read_dataflash (img_addr + h_size, d_size, 470 (char *)(ram_addr + h_size)); 471 472 } 473 #endif /* CONFIG_HAS_DATAFLASH */ 474 475 return ram_addr; 476 } 477 478 /** 479 * image_get_ramdisk - get and verify ramdisk image 480 * @cmdtp: command table pointer 481 * @flag: command flag 482 * @argc: command argument count 483 * @argv: command argument list 484 * @rd_addr: ramdisk image start address 485 * @arch: expected ramdisk architecture 486 * @verify: checksum verification flag 487 * 488 * image_get_ramdisk() returns a pointer to the verified ramdisk image 489 * header. Routine receives image start address and expected architecture 490 * flag. Verification done covers data and header integrity and os/type/arch 491 * fields checking. 492 * 493 * If dataflash support is enabled routine checks for dataflash addresses 494 * and handles required dataflash reads. 495 * 496 * returns: 497 * pointer to a ramdisk image header, if image was found and valid 498 * otherwise, return NULL 499 */ 500 static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, 501 int argc, char *argv[], 502 ulong rd_addr, uint8_t arch, int verify) 503 { 504 image_header_t *rd_hdr; 505 506 show_boot_progress (9); 507 rd_hdr = (image_header_t *)rd_addr; 508 509 if (!image_check_magic (rd_hdr)) { 510 puts ("Bad Magic Number\n"); 511 show_boot_progress (-10); 512 return NULL; 513 } 514 515 if (!image_check_hcrc (rd_hdr)) { 516 puts ("Bad Header Checksum\n"); 517 show_boot_progress (-11); 518 return NULL; 519 } 520 521 show_boot_progress (10); 522 image_print_contents (rd_hdr); 523 524 if (verify) { 525 puts(" Verifying Checksum ... "); 526 if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { 527 puts ("Bad Data CRC\n"); 528 show_boot_progress (-12); 529 return NULL; 530 } 531 puts("OK\n"); 532 } 533 534 show_boot_progress (11); 535 536 if (!image_check_os (rd_hdr, IH_OS_LINUX) || 537 !image_check_arch (rd_hdr, arch) || 538 !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { 539 printf ("No Linux %s Ramdisk Image\n", 540 image_get_arch_name(arch)); 541 show_boot_progress (-13); 542 return NULL; 543 } 544 545 return rd_hdr; 546 } 547 548 /** 549 * get_ramdisk - main ramdisk handling routine 550 * @cmdtp: command table pointer 551 * @flag: command flag 552 * @argc: command argument count 553 * @argv: command argument list 554 * @images: pointer to the bootm images structure 555 * @arch: expected ramdisk architecture 556 * @rd_start: pointer to a ulong variable, will hold ramdisk start address 557 * @rd_end: pointer to a ulong variable, will hold ramdisk end 558 * 559 * get_ramdisk() is responsible for finding a valid ramdisk image. 560 * Curently supported are the following ramdisk sources: 561 * - multicomponent kernel/ramdisk image, 562 * - commandline provided address of decicated ramdisk image. 563 * 564 * returns: 565 * rd_start and rd_end are set to ramdisk start/end addresses if 566 * ramdisk image is found and valid 567 * rd_start and rd_end are set to 0 if no ramdisk exists 568 * return 1 if ramdisk image is found but corrupted 569 */ 570 int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], 571 bootm_headers_t *images, uint8_t arch, 572 ulong *rd_start, ulong *rd_end) 573 { 574 ulong rd_addr, rd_load; 575 ulong rd_data, rd_len; 576 image_header_t *rd_hdr; 577 #if defined(CONFIG_FIT) 578 void *fit_hdr; 579 const char *fit_uname_config = NULL; 580 const char *fit_uname_ramdisk = NULL; 581 ulong default_addr; 582 #endif 583 584 /* 585 * Look for a '-' which indicates to ignore the 586 * ramdisk argument 587 */ 588 if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { 589 debug ("## Skipping init Ramdisk\n"); 590 rd_len = rd_data = 0; 591 } else if (argc >= 3) { 592 #if defined(CONFIG_FIT) 593 /* 594 * If the init ramdisk comes from the FIT image and the FIT image 595 * address is omitted in the command line argument, try to use 596 * os FIT image address or default load address. 597 */ 598 if (images->fit_uname_os) 599 default_addr = (ulong)images->fit_hdr_os; 600 else 601 default_addr = load_addr; 602 603 if (fit_parse_conf (argv[2], default_addr, 604 &rd_addr, &fit_uname_config)) { 605 debug ("* ramdisk: config '%s' from image at 0x%08lx\n", 606 fit_uname_config, rd_addr); 607 } else if (fit_parse_subimage (argv[2], default_addr, 608 &rd_addr, &fit_uname_ramdisk)) { 609 debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", 610 fit_uname_ramdisk, rd_addr); 611 } else 612 #endif 613 { 614 rd_addr = simple_strtoul(argv[2], NULL, 16); 615 debug ("* ramdisk: cmdline image address = 0x%08lx\n", 616 rd_addr); 617 } 618 619 /* copy from dataflash if needed */ 620 printf ("## Loading init Ramdisk Image at %08lx ...\n", 621 rd_addr); 622 rd_addr = gen_get_image (rd_addr); 623 624 /* 625 * Check if there is an initrd image at the 626 * address provided in the second bootm argument 627 * check image type, for FIT images get FIT node. 628 */ 629 switch (gen_image_get_format ((void *)rd_addr)) { 630 case IMAGE_FORMAT_LEGACY: 631 632 debug ("* ramdisk: legacy format image\n"); 633 634 rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, 635 rd_addr, arch, images->verify); 636 637 if (rd_hdr == NULL) { 638 *rd_start = 0; 639 *rd_end = 0; 640 return 1; 641 } 642 643 rd_data = image_get_data (rd_hdr); 644 rd_len = image_get_data_size (rd_hdr); 645 rd_load = image_get_load (rd_hdr); 646 break; 647 #if defined(CONFIG_FIT) 648 case IMAGE_FORMAT_FIT: 649 fit_hdr = (void *)rd_addr; 650 debug ("* ramdisk: FIT format image\n"); 651 fit_unsupported_reset ("ramdisk"); 652 return 1; 653 #endif 654 default: 655 printf ("Wrong Image Format for %s command\n", 656 cmdtp->name); 657 rd_data = rd_len = 0; 658 } 659 660 #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) 661 /* 662 * We need to copy the ramdisk to SRAM to let Linux boot 663 */ 664 if (rd_data) { 665 memmove ((void *)rd_load, (uchar *)rd_data, rd_len); 666 rd_data = rd_load; 667 } 668 #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ 669 670 } else if (images->legacy_hdr_valid && 671 image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { 672 /* 673 * Now check if we have a legacy mult-component image, 674 * get second entry data start address and len. 675 */ 676 show_boot_progress (13); 677 printf ("## Loading init Ramdisk from multi component " 678 "Image at %08lx ...\n", 679 (ulong)images->legacy_hdr_os); 680 681 image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len); 682 } else { 683 /* 684 * no initrd image 685 */ 686 show_boot_progress (14); 687 rd_len = rd_data = 0; 688 } 689 690 if (!rd_data) { 691 debug ("## No init Ramdisk\n"); 692 *rd_start = 0; 693 *rd_end = 0; 694 } else { 695 *rd_start = rd_data; 696 *rd_end = rd_data + rd_len; 697 } 698 debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", 699 *rd_start, *rd_end); 700 701 return 0; 702 } 703 704 #if defined(CONFIG_PPC) || defined(CONFIG_M68K) 705 /** 706 * ramdisk_high - relocate init ramdisk 707 * @rd_data: ramdisk data start address 708 * @rd_len: ramdisk data length 709 * @sp_limit: stack pointer limit (including BOOTMAPSZ) 710 * @sp: current stack pointer 711 * @initrd_start: pointer to a ulong variable, will hold final init ramdisk 712 * start address (after possible relocation) 713 * @initrd_end: pointer to a ulong variable, will hold final init ramdisk 714 * end address (after possible relocation) 715 * 716 * ramdisk_high() takes a relocation hint from "initrd_high" environement 717 * variable and if requested ramdisk data is moved to a specified location. 718 * 719 * returns: 720 * - initrd_start and initrd_end are set to final (after relocation) ramdisk 721 * start/end addresses if ramdisk image start and len were provided 722 * otherwise set initrd_start and initrd_end set to zeros 723 * - returns new allc_current, next free address below BOOTMAPSZ 724 */ 725 ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, 726 ulong sp_limit, ulong sp, 727 ulong *initrd_start, ulong *initrd_end) 728 { 729 char *s; 730 ulong initrd_high; 731 int initrd_copy_to_ram = 1; 732 ulong new_alloc_current = alloc_current; 733 734 if ((s = getenv ("initrd_high")) != NULL) { 735 /* a value of "no" or a similar string will act like 0, 736 * turning the "load high" feature off. This is intentional. 737 */ 738 initrd_high = simple_strtoul (s, NULL, 16); 739 if (initrd_high == ~0) 740 initrd_copy_to_ram = 0; 741 } else { 742 /* not set, no restrictions to load high */ 743 initrd_high = ~0; 744 } 745 746 #ifdef CONFIG_LOGBUFFER 747 /* Prevent initrd from overwriting logbuffer */ 748 if (initrd_high < (gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD)) 749 initrd_high = gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD; 750 debug ("## Logbuffer at 0x%08lx ", gd->bd->bi_memsize - LOGBUFF_LEN); 751 #endif 752 debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", 753 initrd_high, initrd_copy_to_ram); 754 755 if (rd_data) { 756 if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ 757 debug (" in-place initrd\n"); 758 *initrd_start = rd_data; 759 *initrd_end = rd_data + rd_len; 760 } else { 761 new_alloc_current = alloc_current - rd_len; 762 *initrd_start = new_alloc_current; 763 *initrd_start &= ~(4096 - 1); /* align on page */ 764 765 if (initrd_high) { 766 ulong nsp; 767 768 /* 769 * the inital ramdisk does not need to be within 770 * CFG_BOOTMAPSZ as it is not accessed until after 771 * the mm system is initialised. 772 * 773 * do the stack bottom calculation again and see if 774 * the initrd will fit just below the monitor stack 775 * bottom without overwriting the area allocated 776 * for command line args and board info. 777 */ 778 nsp = sp; 779 nsp -= 2048; /* just to be sure */ 780 nsp &= ~0xF; 781 782 if (nsp > initrd_high) /* limit as specified */ 783 nsp = initrd_high; 784 785 nsp -= rd_len; 786 nsp &= ~(4096 - 1); /* align on page */ 787 788 if (nsp >= sp_limit) { 789 *initrd_start = nsp; 790 new_alloc_current = alloc_current; 791 } 792 } 793 794 show_boot_progress (12); 795 796 *initrd_end = *initrd_start + rd_len; 797 printf (" Loading Ramdisk to %08lx, end %08lx ... ", 798 *initrd_start, *initrd_end); 799 800 memmove_wd((void *)*initrd_start, 801 (void *)rd_data, rd_len, CHUNKSZ); 802 803 puts ("OK\n"); 804 } 805 } else { 806 *initrd_start = 0; 807 *initrd_end = 0; 808 } 809 debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", 810 *initrd_start, *initrd_end); 811 812 return new_alloc_current; 813 } 814 815 /** 816 * get_boot_sp_limit - calculate stack pointer limit 817 * @sp: current stack pointer 818 * 819 * get_boot_sp_limit() takes current stack pointer adrress and calculates 820 * stack pointer limit, below which kernel boot data (cmdline, board info, 821 * etc.) will be allocated. 822 * 823 * returns: 824 * stack pointer limit 825 */ 826 ulong get_boot_sp_limit(ulong sp) 827 { 828 ulong sp_limit = sp; 829 830 sp_limit -= 2048; /* just to be sure */ 831 832 /* make sure sp_limit is within kernel mapped space */ 833 if (sp_limit > CFG_BOOTMAPSZ) 834 sp_limit = CFG_BOOTMAPSZ; 835 sp_limit &= ~0xF; 836 837 return sp_limit; 838 } 839 840 /** 841 * get_boot_cmdline - allocate and initialize kernel cmdline 842 * @alloc_current: current boot allocation address (counting down 843 * from sp_limit) 844 * @cmd_start: pointer to a ulong variable, will hold cmdline start 845 * @cmd_end: pointer to a ulong variable, will hold cmdline end 846 * 847 * get_boot_cmdline() allocates space for kernel command line below 848 * provided alloc_current address. If "bootargs" U-boot environemnt 849 * variable is present its contents is copied to allocated kernel 850 * command line. 851 * 852 * returns: 853 * alloc_current after cmdline allocation 854 */ 855 ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end) 856 { 857 char *cmdline; 858 char *s; 859 860 cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF); 861 862 if ((s = getenv("bootargs")) == NULL) 863 s = ""; 864 865 strcpy(cmdline, s); 866 867 *cmd_start = (ulong) & cmdline[0]; 868 *cmd_end = *cmd_start + strlen(cmdline); 869 870 debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); 871 872 return (ulong)cmdline; 873 } 874 875 /** 876 * get_boot_kbd - allocate and initialize kernel copy of board info 877 * @alloc_current: current boot allocation address (counting down 878 * from sp_limit) 879 * @kbd: double pointer to board info data 880 * 881 * get_boot_kbd() - allocates space for kernel copy of board info data. 882 * Space is allocated below provided alloc_current address and kernel 883 * board info is initialized with the current u-boot board info data. 884 * 885 * returns: 886 * alloc_current after kbd allocation 887 */ 888 ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) 889 { 890 *kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF); 891 **kbd = *(gd->bd); 892 893 debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); 894 895 #if defined(DEBUG) && defined(CONFIG_CMD_BDI) 896 do_bdinfo(NULL, 0, 0, NULL); 897 #endif 898 899 return (ulong)*kbd; 900 } 901 #endif /* CONFIG_PPC || CONFIG_M68K */ 902 903 #if defined(CONFIG_FIT) 904 /*****************************************************************************/ 905 /* New uImage format routines */ 906 /*****************************************************************************/ 907 static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, 908 ulong *addr, const char **name) 909 { 910 const char *sep; 911 912 *addr = addr_curr; 913 *name = NULL; 914 915 sep = strchr (spec, sepc); 916 if (sep) { 917 if (sep - spec > 0) 918 *addr = simple_strtoul (spec, NULL, 16); 919 920 *name = sep + 1; 921 return 1; 922 } 923 924 return 0; 925 } 926 927 /** 928 * fit_parse_conf - parse FIT configuration spec 929 * @spec: input string, containing configuration spec 930 * @add_curr: current image address (to be used as a possible default) 931 * @addr: pointer to a ulong variable, will hold FIT image address of a given 932 * configuration 933 * @conf_name double pointer to a char, will hold pointer to a configuration 934 * unit name 935 * 936 * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, 937 * where <addr> is a FIT image address that contains configuration 938 * with a <conf> unit name. 939 * 940 * Address part is optional, and if omitted default add_curr will 941 * be used instead. 942 * 943 * returns: 944 * 1 if spec is a valid configuration string, 945 * addr and conf_name are set accordingly 946 * 0 otherwise 947 */ 948 inline int fit_parse_conf (const char *spec, ulong addr_curr, 949 ulong *addr, const char **conf_name) 950 { 951 return fit_parse_spec (spec, '#', addr_curr, addr, conf_name); 952 } 953 954 /** 955 * fit_parse_subimage - parse FIT subimage spec 956 * @spec: input string, containing subimage spec 957 * @add_curr: current image address (to be used as a possible default) 958 * @addr: pointer to a ulong variable, will hold FIT image address of a given 959 * subimage 960 * @image_name: double pointer to a char, will hold pointer to a subimage name 961 * 962 * fit_parse_subimage() expects subimage spec in the for of 963 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains 964 * subimage with a <subimg> unit name. 965 * 966 * Address part is optional, and if omitted default add_curr will 967 * be used instead. 968 * 969 * returns: 970 * 1 if spec is a valid subimage string, 971 * addr and image_name are set accordingly 972 * 0 otherwise 973 */ 974 inline int fit_parse_subimage (const char *spec, ulong addr_curr, 975 ulong *addr, const char **image_name) 976 { 977 return fit_parse_spec (spec, ':', addr_curr, addr, image_name); 978 } 979 980 #endif /* CONFIG_FIT */ 981 982 #endif /* USE_HOSTCC */ 983