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