diff --git a/arch/aarch64/linker.lds.S b/arch/aarch64/linker.lds.S index 6c9b2f4..79e29bf 100644 --- a/arch/aarch64/linker.lds.S +++ b/arch/aarch64/linker.lds.S @@ -85,4 +85,7 @@ SECTIONS #ifdef CONFIG_POSITION_INDEPENDENT _reloc_size = _reloc_end - _reloc_start; #endif +#ifdef CONFIG_LINUX_KRNL_HEADER_IMG + _kernel_size = _stack_end - _start; +#endif } diff --git a/arch/aarch64/linux-kernel-image-header.h b/arch/aarch64/linux-kernel-image-header.h new file mode 100644 index 0000000..079b71d --- /dev/null +++ b/arch/aarch64/linux-kernel-image-header.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Derived info from arch/arm64/kernel/head.S in the Linux kernel. + */ +#ifndef _AARCH64_LINUX_KERNEL_IMAGE_HEADER_H +#define _AARCH64_LINUX_KERNEL_IMAGE_HEADER_H + +/* + * Image header flags (Documentation/arm64/booting.rst): + * Bit 0 Kernel endianness. + 1 if BE, 0 if LE. + * Bit 1-2 Kernel Page size. + 0 - Unspecified. + 1 - 4K + 2 - 16K + 3 - 64K + * Bit 3 Kernel physical placement + 0 + 2MB aligned base should be as close as possible + to the base of DRAM, since memory below it is not + accessible via the linear mapping + 1 + 2MB aligned base such that all image_size bytes + counted from the start of the image are within + the 48-bit addressable range of physical memory + */ +#define LINUX_IMAGE_FLAGS ((1 << 1) | (1 << 3)) + + .macro linux_image_header entry + /* + * DO NOT MODIFY. Image header expected by Linux boot-loaders. + */ + b \entry + .long 0 /* reserved */ + .quad 0 /* text_offset */ + .quad _kernel_size /* image_size, see linker script */ + .quad LINUX_IMAGE_FLAGS /* flags */ + .quad 0 /* reserved */ + .quad 0 /* reserved */ + .quad 0 /* reserved */ + .ascii "ARM\x64" /* magic number */ + .long 0 /* reserved */ + .endm + +#endif /* _AARCH64_LINUX_KERNEL_IMAGE_HEADER_H */ diff --git a/arch/aarch64/reloc.S b/arch/aarch64/reloc.S index 0da0751..b6fb485 100644 --- a/arch/aarch64/reloc.S +++ b/arch/aarch64/reloc.S @@ -4,26 +4,27 @@ */ #include "asmdefs.h" +#ifdef CONFIG_LINUX_KRNL_HEADER_IMG +#include "linux-kernel-image-header.h" +#endif + .extern _reloc_size .extern _start ENTRY_ALIAS(_head) +#ifdef CONFIG_LINUX_KRNL_HEADER_IMG + linux_image_header _reloc_entry +#else adr x1, _relocated_uni b _reloc_entry +#endif ENTRY_ALIAS(_rel_stack_base) .quad _start ENTRY_ALIAS(_rel_stack_size) .quad _reloc_size -#ifdef CONFIG_LINUX_KRNL_HEADER_IMG - .quad 0 - .quad 0 - .quad 0 - .quad 0 - .ascii "ARM\x64" - .long 0 -#endif + ENTRY_ALIAS( _reloc_entry) adr x4, _start ldr x5, _rel_stack_base diff --git a/arch/aarch64/start.S b/arch/aarch64/start.S index 75415b1..de454f9 100644 --- a/arch/aarch64/start.S +++ b/arch/aarch64/start.S @@ -4,23 +4,21 @@ */ #include "asmdefs.h" -.section .text #ifdef CONFIG_LINUX_KRNL_HEADER_IMG +#include "linux-kernel-image-header.h" +#endif + +.section .text + +#if defined(CONFIG_LINUX_KRNL_HEADER_IMG) && !defined(CONFIG_POSITION_INDEPENDENT) _head: - ldr x1, =_start - b _start + linux_image_header _start _stack_base: .quad 0x0 _stack_size: .quad _stack_end - .quad 0 - .quad 0 - .quad 0 - .quad 0 - .ascii "ARM\x64" - .long 0 .align 4 #endif