image.c 2.0 KB

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