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 * @lmb: pointer to lmb handle, will be used for memory mgmt 708 * @rd_data: ramdisk data start address 709 * @rd_len: ramdisk data length 710 * @initrd_start: pointer to a ulong variable, will hold final init ramdisk 711 * start address (after possible relocation) 712 * @initrd_end: pointer to a ulong variable, will hold final init ramdisk 713 * end address (after possible relocation) 714 * 715 * ramdisk_high() takes a relocation hint from "initrd_high" environement 716 * variable and if requested ramdisk data is moved to a specified location. 717 * 718 * returns: 719 * - initrd_start and initrd_end are set to final (after relocation) ramdisk 720 * start/end addresses if ramdisk image start and len were provided 721 * otherwise set initrd_start and initrd_end set to zeros 722 * - returns: 723 * 0 - success 724 * -1 - failure 725 */ 726 int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, 727 ulong *initrd_start, ulong *initrd_end) 728 { 729 char *s; 730 ulong initrd_high; 731 int initrd_copy_to_ram = 1; 732 733 if ((s = getenv ("initrd_high")) != NULL) { 734 /* a value of "no" or a similar string will act like 0, 735 * turning the "load high" feature off. This is intentional. 736 */ 737 initrd_high = simple_strtoul (s, NULL, 16); 738 if (initrd_high == ~0) 739 initrd_copy_to_ram = 0; 740 } else { 741 /* not set, no restrictions to load high */ 742 initrd_high = ~0; 743 } 744 745 debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", 746 initrd_high, initrd_copy_to_ram); 747 748 if (rd_data) { 749 if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ 750 debug (" in-place initrd\n"); 751 *initrd_start = rd_data; 752 *initrd_end = rd_data + rd_len; 753 lmb_reserve(lmb, rd_data, rd_len); 754 } else { 755 if (initrd_high) 756 *initrd_start = lmb_alloc_base(lmb, rd_len, 0x1000, initrd_high); 757 else 758 *initrd_start = lmb_alloc(lmb, rd_len, 0x1000); 759 760 if (*initrd_start == 0) { 761 puts("ramdisk - allocation error\n"); 762 goto error; 763 } 764 show_boot_progress (12); 765 766 *initrd_end = *initrd_start + rd_len; 767 printf (" Loading Ramdisk to %08lx, end %08lx ... ", 768 *initrd_start, *initrd_end); 769 770 memmove_wd((void *)*initrd_start, 771 (void *)rd_data, rd_len, CHUNKSZ); 772 773 puts ("OK\n"); 774 } 775 } else { 776 *initrd_start = 0; 777 *initrd_end = 0; 778 } 779 debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", 780 *initrd_start, *initrd_end); 781 return 0; 782 783 error: 784 return -1; 785 } 786 787 /** 788 * get_boot_cmdline - allocate and initialize kernel cmdline 789 * @lmb: pointer to lmb handle, will be used for memory mgmt 790 * @cmd_start: pointer to a ulong variable, will hold cmdline start 791 * @cmd_end: pointer to a ulong variable, will hold cmdline end 792 * @bootmap_base: ulong variable, holds offset in physical memory to 793 * base of bootmap 794 * 795 * get_boot_cmdline() allocates space for kernel command line below 796 * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt 797 * variable is present its contents is copied to allocated kernel 798 * command line. 799 * 800 * returns: 801 * 0 - success 802 * -1 - failure 803 */ 804 int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, 805 ulong bootmap_base) 806 { 807 char *cmdline; 808 char *s; 809 810 cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf, 811 CFG_BOOTMAPSZ + bootmap_base); 812 813 if (cmdline == NULL) 814 return -1; 815 816 if ((s = getenv("bootargs")) == NULL) 817 s = ""; 818 819 strcpy(cmdline, s); 820 821 *cmd_start = (ulong) & cmdline[0]; 822 *cmd_end = *cmd_start + strlen(cmdline); 823 824 debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); 825 826 return 0; 827 } 828 829 /** 830 * get_boot_kbd - allocate and initialize kernel copy of board info 831 * @lmb: pointer to lmb handle, will be used for memory mgmt 832 * @kbd: double pointer to board info data 833 * @bootmap_base: ulong variable, holds offset in physical memory to 834 * base of bootmap 835 * 836 * get_boot_kbd() allocates space for kernel copy of board info data below 837 * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with 838 * the current u-boot board info data. 839 * 840 * returns: 841 * 0 - success 842 * -1 - failure 843 */ 844 int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) 845 { 846 *kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, 847 CFG_BOOTMAPSZ + bootmap_base); 848 if (*kbd == NULL) 849 return -1; 850 851 **kbd = *(gd->bd); 852 853 debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); 854 855 #if defined(DEBUG) && defined(CONFIG_CMD_BDI) 856 do_bdinfo(NULL, 0, 0, NULL); 857 #endif 858 859 return 0; 860 } 861 #endif /* CONFIG_PPC || CONFIG_M68K */ 862 863 #if defined(CONFIG_FIT) 864 /*****************************************************************************/ 865 /* New uImage format routines */ 866 /*****************************************************************************/ 867 static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, 868 ulong *addr, const char **name) 869 { 870 const char *sep; 871 872 *addr = addr_curr; 873 *name = NULL; 874 875 sep = strchr (spec, sepc); 876 if (sep) { 877 if (sep - spec > 0) 878 *addr = simple_strtoul (spec, NULL, 16); 879 880 *name = sep + 1; 881 return 1; 882 } 883 884 return 0; 885 } 886 887 /** 888 * fit_parse_conf - parse FIT configuration spec 889 * @spec: input string, containing configuration spec 890 * @add_curr: current image address (to be used as a possible default) 891 * @addr: pointer to a ulong variable, will hold FIT image address of a given 892 * configuration 893 * @conf_name double pointer to a char, will hold pointer to a configuration 894 * unit name 895 * 896 * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, 897 * where <addr> is a FIT image address that contains configuration 898 * with a <conf> unit name. 899 * 900 * Address part is optional, and if omitted default add_curr will 901 * be used instead. 902 * 903 * returns: 904 * 1 if spec is a valid configuration string, 905 * addr and conf_name are set accordingly 906 * 0 otherwise 907 */ 908 inline int fit_parse_conf (const char *spec, ulong addr_curr, 909 ulong *addr, const char **conf_name) 910 { 911 return fit_parse_spec (spec, '#', addr_curr, addr, conf_name); 912 } 913 914 /** 915 * fit_parse_subimage - parse FIT subimage spec 916 * @spec: input string, containing subimage spec 917 * @add_curr: current image address (to be used as a possible default) 918 * @addr: pointer to a ulong variable, will hold FIT image address of a given 919 * subimage 920 * @image_name: double pointer to a char, will hold pointer to a subimage name 921 * 922 * fit_parse_subimage() expects subimage spec in the for of 923 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains 924 * subimage with a <subimg> unit name. 925 * 926 * Address part is optional, and if omitted default add_curr will 927 * be used instead. 928 * 929 * returns: 930 * 1 if spec is a valid subimage string, 931 * addr and image_name are set accordingly 932 * 0 otherwise 933 */ 934 inline int fit_parse_subimage (const char *spec, ulong addr_curr, 935 ulong *addr, const char **image_name) 936 { 937 return fit_parse_spec (spec, ':', addr_curr, addr, image_name); 938 } 939 940 #endif /* CONFIG_FIT */ 941 942 #endif /* USE_HOSTCC */ 943