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
, ++phdr
) {
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
));
108 if (ehdr
->e_machine
== EM_PPC64
&& (ehdr
->e_flags
&
109 EF_PPC64_ELFV1_ABI
)) {
111 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
112 * descriptor pointer with the first double word being the
113 * address of the entry point of the function.
115 uintptr_t addr
= ehdr
->e_entry
;
117 return *(Elf64_Addr
*)addr
;
120 return ehdr
->e_entry
;
123 unsigned long load_elf64_image_shdr(unsigned long addr
)
125 Elf64_Ehdr
*ehdr
; /* Elf header structure pointer */
126 Elf64_Shdr
*shdr
; /* Section header structure pointer */
127 unsigned char *strtab
= 0; /* String table pointer */
128 unsigned char *image
; /* Binary image pointer */
129 int i
; /* Loop counter */
131 ehdr
= (Elf64_Ehdr
*)addr
;
133 /* Find the section header string table for output info */
134 shdr
= (Elf64_Shdr
*)(addr
+ (ulong
)ehdr
->e_shoff
+
135 (ehdr
->e_shstrndx
* sizeof(Elf64_Shdr
)));
137 if (shdr
->sh_type
== SHT_STRTAB
)
138 strtab
= (unsigned char *)(addr
+ (ulong
)shdr
->sh_offset
);
140 /* Load each appropriate section */
141 for (i
= 0; i
< ehdr
->e_shnum
; ++i
) {
142 shdr
= (Elf64_Shdr
*)(addr
+ (ulong
)ehdr
->e_shoff
+
143 (i
* sizeof(Elf64_Shdr
)));
145 if (!(shdr
->sh_flags
& SHF_ALLOC
) ||
146 shdr
->sh_addr
== 0 || shdr
->sh_size
== 0) {
151 debug("%sing %s @ 0x%08lx (%ld bytes)\n",
152 (shdr
->sh_type
== SHT_NOBITS
) ? "Clear" : "Load",
153 &strtab
[shdr
->sh_name
],
154 (unsigned long)shdr
->sh_addr
,
155 (long)shdr
->sh_size
);
158 if (shdr
->sh_type
== SHT_NOBITS
) {
159 memset((void *)(uintptr_t)shdr
->sh_addr
, 0,
162 image
= (unsigned char *)addr
+ (ulong
)shdr
->sh_offset
;
163 memcpy((void *)(uintptr_t)shdr
->sh_addr
,
164 (const void *)image
, shdr
->sh_size
);
166 flush_cache(rounddown(shdr
->sh_addr
, ARCH_DMA_MINALIGN
),
167 roundup((shdr
->sh_addr
+ shdr
->sh_size
),
169 rounddown(shdr
->sh_addr
, ARCH_DMA_MINALIGN
));
172 if (ehdr
->e_machine
== EM_PPC64
&& (ehdr
->e_flags
&
173 EF_PPC64_ELFV1_ABI
)) {
175 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
176 * descriptor pointer with the first double word being the
177 * address of the entry point of the function.
179 uintptr_t addr
= ehdr
->e_entry
;
181 return *(Elf64_Addr
*)addr
;
184 return ehdr
->e_entry
;
188 * A very simple ELF loader, assumes the image is valid, returns the
189 * entry point address.
191 * The loader firstly reads the EFI class to see if it's a 64-bit image.
192 * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
194 unsigned long load_elf_image_phdr(unsigned long addr
)
196 Elf32_Ehdr
*ehdr
; /* Elf header structure pointer */
197 Elf32_Phdr
*phdr
; /* Program header structure pointer */
200 ehdr
= (Elf32_Ehdr
*)addr
;
201 if (ehdr
->e_ident
[EI_CLASS
] == ELFCLASS64
)
202 return load_elf64_image_phdr(addr
);
204 phdr
= (Elf32_Phdr
*)(addr
+ ehdr
->e_phoff
);
206 /* Load each program header */
207 for (i
= 0; i
< ehdr
->e_phnum
; ++i
, ++phdr
) {
208 void *dst
= (void *)(uintptr_t)phdr
->p_paddr
;
209 void *src
= (void *)addr
+ phdr
->p_offset
;
211 /* Only load PT_LOAD program header */
212 if (phdr
->p_type
!= PT_LOAD
)
215 debug("Loading phdr %i to 0x%p (%i bytes)\n",
216 i
, dst
, phdr
->p_filesz
);
218 memcpy(dst
, src
, phdr
->p_filesz
);
219 if (phdr
->p_filesz
!= phdr
->p_memsz
)
220 memset(dst
+ phdr
->p_filesz
, 0x00,
221 phdr
->p_memsz
- phdr
->p_filesz
);
222 flush_cache(rounddown((unsigned long)dst
, ARCH_DMA_MINALIGN
),
223 roundup(phdr
->p_memsz
, ARCH_DMA_MINALIGN
));
226 return ehdr
->e_entry
;
229 unsigned long load_elf_image_shdr(unsigned long addr
)
231 Elf32_Ehdr
*ehdr
; /* Elf header structure pointer */
232 Elf32_Shdr
*shdr
; /* Section header structure pointer */
233 unsigned char *strtab
= 0; /* String table pointer */
234 unsigned char *image
; /* Binary image pointer */
235 int i
; /* Loop counter */
237 ehdr
= (Elf32_Ehdr
*)addr
;
238 if (ehdr
->e_ident
[EI_CLASS
] == ELFCLASS64
)
239 return load_elf64_image_shdr(addr
);
241 /* Find the section header string table for output info */
242 shdr
= (Elf32_Shdr
*)(addr
+ ehdr
->e_shoff
+
243 (ehdr
->e_shstrndx
* sizeof(Elf32_Shdr
)));
245 if (shdr
->sh_type
== SHT_STRTAB
)
246 strtab
= (unsigned char *)(addr
+ shdr
->sh_offset
);
248 /* Load each appropriate section */
249 for (i
= 0; i
< ehdr
->e_shnum
; ++i
) {
250 shdr
= (Elf32_Shdr
*)(addr
+ ehdr
->e_shoff
+
251 (i
* sizeof(Elf32_Shdr
)));
253 if (!(shdr
->sh_flags
& SHF_ALLOC
) ||
254 shdr
->sh_addr
== 0 || shdr
->sh_size
== 0) {
259 debug("%sing %s @ 0x%08lx (%ld bytes)\n",
260 (shdr
->sh_type
== SHT_NOBITS
) ? "Clear" : "Load",
261 &strtab
[shdr
->sh_name
],
262 (unsigned long)shdr
->sh_addr
,
263 (long)shdr
->sh_size
);
266 if (shdr
->sh_type
== SHT_NOBITS
) {
267 memset((void *)(uintptr_t)shdr
->sh_addr
, 0,
270 image
= (unsigned char *)addr
+ shdr
->sh_offset
;
271 memcpy((void *)(uintptr_t)shdr
->sh_addr
,
272 (const void *)image
, shdr
->sh_size
);
274 flush_cache(rounddown(shdr
->sh_addr
, ARCH_DMA_MINALIGN
),
275 roundup((shdr
->sh_addr
+ shdr
->sh_size
),
277 rounddown(shdr
->sh_addr
, ARCH_DMA_MINALIGN
));
280 return ehdr
->e_entry
;
284 * Determine if a valid ELF image exists at the given memory location.
285 * First look at the ELF header magic field, then make sure that it is
288 int valid_elf_image(unsigned long addr
)
290 Elf32_Ehdr
*ehdr
; /* Elf header structure pointer */
292 ehdr
= (Elf32_Ehdr
*)addr
;
294 if (!IS_ELF(*ehdr
)) {
295 printf("## No elf image at address 0x%08lx\n", addr
);
299 if (ehdr
->e_type
!= ET_EXEC
) {
300 printf("## Not a 32-bit elf image at address 0x%08lx\n", addr
);