1 // SPDX-License-Identifier: BSD-2-Clause
3 Copyright (c) 2001 William L. Pitts
16 #include <linux/linkage.h>
20 * bootelf_exec() - start the ELF image execution.
22 * @entry: address of entry point of ELF.
24 * May by used to allow ports to override the default behavior.
26 unsigned long bootelf_exec(ulong (*entry)(int, char * const[]),
27 int argc, char *const argv[])
29 return entry(argc, argv);
33 * bootelf() - Boot ELF from memory.
35 * @addr: Loading address of ELF in memory.
36 * @flags: Bits like ELF_PHDR to control boot details.
37 * @argc: May be used to pass command line arguments (maybe unused).
38 * Necessary for backward compatibility with the CLI command.
39 * If unused, must be 0.
40 * @argv: see @argc. If unused, must be NULL.
41 * Return: Number returned by ELF application.
43 * Sets errno = ENOEXEC if the ELF image is not valid.
45 unsigned long bootelf(unsigned long addr, Bootelf_flags flags,
46 int argc, char *const argv[])
48 unsigned long entry_addr;
49 char *args[] = {"", NULL};
53 if (!valid_elf_image(addr)) {
58 entry_addr = flags.phdr ? load_elf_image_phdr(addr)
59 : load_elf_image_shdr(addr);
69 return bootelf_exec((void *)entry_addr, argc, argv);
73 * A very simple ELF64 loader, assumes the image is valid, returns the
74 * entry point address.
76 * Note if U-Boot is 32-bit, the loader assumes the to segment's
77 * physical address and size is within the lower 32-bit address space.
79 unsigned long load_elf64_image_phdr(unsigned long addr)
81 Elf64_Ehdr *ehdr; /* Elf header structure pointer */
82 Elf64_Phdr *phdr; /* Program header structure pointer */
85 ehdr = (Elf64_Ehdr *)addr;
86 phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
88 /* Load each program header */
89 for (i = 0; i < ehdr->e_phnum; ++i) {
90 void *dst = (void *)(ulong)phdr->p_paddr;
91 void *src = (void *)addr + phdr->p_offset;
93 /* Only load PT_LOAD program header */
94 if (phdr->p_type != PT_LOAD)
97 debug("Loading phdr %i to 0x%p (%lu bytes)\n",
98 i, dst, (ulong)phdr->p_filesz);
100 memcpy(dst, src, phdr->p_filesz);
101 if (phdr->p_filesz != phdr->p_memsz)
102 memset(dst + phdr->p_filesz, 0x00,
103 phdr->p_memsz - phdr->p_filesz);
104 flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
105 roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
109 if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
110 EF_PPC64_ELFV1_ABI)) {
112 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
113 * descriptor pointer with the first double word being the
114 * address of the entry point of the function.
116 uintptr_t addr = ehdr->e_entry;
118 return *(Elf64_Addr *)addr;
121 return ehdr->e_entry;
124 unsigned long load_elf64_image_shdr(unsigned long addr)
126 Elf64_Ehdr *ehdr; /* Elf header structure pointer */
127 Elf64_Shdr *shdr; /* Section header structure pointer */
128 unsigned char *strtab = 0; /* String table pointer */
129 unsigned char *image; /* Binary image pointer */
130 int i; /* Loop counter */
132 ehdr = (Elf64_Ehdr *)addr;
134 /* Find the section header string table for output info */
135 shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
136 (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
138 if (shdr->sh_type == SHT_STRTAB)
139 strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
141 /* Load each appropriate section */
142 for (i = 0; i < ehdr->e_shnum; ++i) {
143 shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
144 (i * sizeof(Elf64_Shdr)));
146 if (!(shdr->sh_flags & SHF_ALLOC) ||
147 shdr->sh_addr == 0 || shdr->sh_size == 0) {
152 debug("%sing %s @ 0x%08lx (%ld bytes)\n",
153 (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
154 &strtab[shdr->sh_name],
155 (unsigned long)shdr->sh_addr,
156 (long)shdr->sh_size);
159 if (shdr->sh_type == SHT_NOBITS) {
160 memset((void *)(uintptr_t)shdr->sh_addr, 0,
163 image = (unsigned char *)addr + (ulong)shdr->sh_offset;
164 memcpy((void *)(uintptr_t)shdr->sh_addr,
165 (const void *)image, shdr->sh_size);
167 flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
168 roundup((shdr->sh_addr + shdr->sh_size),
170 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
173 if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
174 EF_PPC64_ELFV1_ABI)) {
176 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
177 * descriptor pointer with the first double word being the
178 * address of the entry point of the function.
180 uintptr_t addr = ehdr->e_entry;
182 return *(Elf64_Addr *)addr;
185 return ehdr->e_entry;
189 * A very simple ELF loader, assumes the image is valid, returns the
190 * entry point address.
192 * The loader firstly reads the EFI class to see if it's a 64-bit image.
193 * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
195 unsigned long load_elf_image_phdr(unsigned long addr)
197 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
198 Elf32_Phdr *phdr; /* Program header structure pointer */
201 ehdr = (Elf32_Ehdr *)addr;
202 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
203 return load_elf64_image_phdr(addr);
205 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
207 /* Load each program header */
208 for (i = 0; i < ehdr->e_phnum; ++i) {
209 void *dst = (void *)(uintptr_t)phdr->p_paddr;
210 void *src = (void *)addr + phdr->p_offset;
212 /* Only load PT_LOAD program header */
213 if (phdr->p_type != PT_LOAD)
216 debug("Loading phdr %i to 0x%p (%i bytes)\n",
217 i, dst, phdr->p_filesz);
219 memcpy(dst, src, phdr->p_filesz);
220 if (phdr->p_filesz != phdr->p_memsz)
221 memset(dst + phdr->p_filesz, 0x00,
222 phdr->p_memsz - phdr->p_filesz);
223 flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
224 roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
228 return ehdr->e_entry;
231 unsigned long load_elf_image_shdr(unsigned long addr)
233 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
234 Elf32_Shdr *shdr; /* Section header structure pointer */
235 unsigned char *strtab = 0; /* String table pointer */
236 unsigned char *image; /* Binary image pointer */
237 int i; /* Loop counter */
239 ehdr = (Elf32_Ehdr *)addr;
240 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
241 return load_elf64_image_shdr(addr);
243 /* Find the section header string table for output info */
244 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
245 (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
247 if (shdr->sh_type == SHT_STRTAB)
248 strtab = (unsigned char *)(addr + shdr->sh_offset);
250 /* Load each appropriate section */
251 for (i = 0; i < ehdr->e_shnum; ++i) {
252 shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
253 (i * sizeof(Elf32_Shdr)));
255 if (!(shdr->sh_flags & SHF_ALLOC) ||
256 shdr->sh_addr == 0 || shdr->sh_size == 0) {
261 debug("%sing %s @ 0x%08lx (%ld bytes)\n",
262 (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
263 &strtab[shdr->sh_name],
264 (unsigned long)shdr->sh_addr,
265 (long)shdr->sh_size);
268 if (shdr->sh_type == SHT_NOBITS) {
269 memset((void *)(uintptr_t)shdr->sh_addr, 0,
272 image = (unsigned char *)addr + shdr->sh_offset;
273 memcpy((void *)(uintptr_t)shdr->sh_addr,
274 (const void *)image, shdr->sh_size);
276 flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
277 roundup((shdr->sh_addr + shdr->sh_size),
279 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
282 return ehdr->e_entry;
286 * Determine if a valid ELF image exists at the given memory location.
287 * First look at the ELF header magic field, then make sure that it is
290 int valid_elf_image(unsigned long addr)
292 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
294 ehdr = (Elf32_Ehdr *)addr;
296 if (!IS_ELF(*ehdr)) {
297 printf("## No elf image at address 0x%08lx\n", addr);
301 if (ehdr->e_type != ET_EXEC) {
302 printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);