@@ -4,8 +4,6 @@
CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
-CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) \
- -I$(src)/../../../scripts/dtc/libfdt
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
@@ -11,6 +11,7 @@
*/
#include <linux/efi.h>
#include <asm/efi.h>
+#include <asm/image_hdr.h>
#include <asm/sections.h>
@@ -24,20 +25,30 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
{
efi_status_t status;
unsigned long kernel_size, kernel_memsize = 0;
+ struct image_hdr *hdr = (struct image_hdr *)*image_addr;
+ unsigned long image_base;
+
+ /* make sure image_addr points to an arm64 kernel Image */
+ if (!image_hdr_check(hdr)) {
+ pr_efi_err(sys_table, "Kernel Image header corrupt\n");
+ return EFI_LOAD_ERROR;
+ }
+
+ /* put the image at the offset specified in the Image header */
+ image_base = dram_base + image_hdr_text_offset(hdr);
/* Relocate the image, if required. */
kernel_size = _edata - _text;
- if (*image_addr != (dram_base + TEXT_OFFSET)) {
+ if (*image_addr != image_base) {
kernel_memsize = kernel_size + (_end - _edata);
status = efi_relocate_kernel(sys_table, image_addr,
kernel_size, kernel_memsize,
- dram_base + TEXT_OFFSET,
- PAGE_SIZE);
+ image_base, PAGE_SIZE);
if (status != EFI_SUCCESS) {
pr_efi_err(sys_table, "Failed to relocate kernel\n");
return status;
}
- if (*image_addr != (dram_base + TEXT_OFFSET)) {
+ if (*image_addr != image_base) {
pr_efi_err(sys_table, "Failed to alloc kernel memory\n");
efi_free(sys_table, kernel_memsize, *image_addr);
return EFI_LOAD_ERROR;
The EFI stub for arm64 needs to behave like an ordinary bootloader in the sense that it needs to inspect the Image header at runtime and not rely on the linker or preprocessor to produce a value for TEXT_OFFSET. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/arm64/kernel/Makefile | 2 -- arch/arm64/kernel/efi-stub.c | 19 +++++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-)