image.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2009
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. */
  6. #include <common.h>
  7. #include <image.h>
  8. #include <mapmem.h>
  9. #include <linux/sizes.h>
  10. DECLARE_GLOBAL_DATA_PTR;
  11. #define LINUX_ARM64_IMAGE_MAGIC 0x644d5241
  12. /* See Documentation/arm64/booting.txt in the Linux kernel */
  13. struct Image_header {
  14. uint32_t code0; /* Executable code */
  15. uint32_t code1; /* Executable code */
  16. uint64_t text_offset; /* Image load offset, LE */
  17. uint64_t image_size; /* Effective Image size, LE */
  18. uint64_t flags; /* Kernel flags, LE */
  19. uint64_t res2; /* reserved */
  20. uint64_t res3; /* reserved */
  21. uint64_t res4; /* reserved */
  22. uint32_t magic; /* Magic number */
  23. uint32_t res5;
  24. };
  25. int booti_setup(ulong image, ulong *relocated_addr, ulong *size,
  26. bool force_reloc)
  27. {
  28. struct Image_header *ih;
  29. uint64_t dst;
  30. uint64_t image_size, text_offset;
  31. *relocated_addr = image;
  32. ih = (struct Image_header *)map_sysmem(image, 0);
  33. if (ih->magic != le32_to_cpu(LINUX_ARM64_IMAGE_MAGIC)) {
  34. puts("Bad Linux ARM64 Image magic!\n");
  35. return 1;
  36. }
  37. /*
  38. * Prior to Linux commit a2c1d73b94ed, the text_offset field
  39. * is of unknown endianness. In these cases, the image_size
  40. * field is zero, and we can assume a fixed value of 0x80000.
  41. */
  42. if (ih->image_size == 0) {
  43. puts("Image lacks image_size field, assuming 16MiB\n");
  44. image_size = 16 << 20;
  45. text_offset = 0x80000;
  46. } else {
  47. image_size = le64_to_cpu(ih->image_size);
  48. text_offset = le64_to_cpu(ih->text_offset);
  49. }
  50. *size = image_size;
  51. /*
  52. * If bit 3 of the flags field is set, the 2MB aligned base of the
  53. * kernel image can be anywhere in physical memory, so respect
  54. * images->ep. Otherwise, relocate the image to the base of RAM
  55. * since memory below it is not accessible via the linear mapping.
  56. */
  57. if (!force_reloc && (le64_to_cpu(ih->flags) & BIT(3)))
  58. dst = image - text_offset;
  59. else
  60. dst = gd->bd->bi_dram[0].start;
  61. *relocated_addr = ALIGN(dst, SZ_2M) + text_offset;
  62. unmap_sysmem(ih);
  63. return 0;
  64. }