mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 14:10:43 +00:00
ARMv8: add optional Linux kernel image header
Allow placing a Linux kernel image header at the start of the U-Boot binary. This is useful since the image header reports the amount of memory (BSS and similar) that U-Boot needs to use, but that isn't part of the binary size. This can be used by the code that loads U-Boot into memory to determine where to load U-Boot, based on other users of memory. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
parent
f097532d27
commit
8163faf952
5 changed files with 159 additions and 1 deletions
|
@ -32,6 +32,23 @@ config SYS_INIT_SP_BSS_OFFSET
|
|||
calculate the stack pointer. This offset should be large enough so
|
||||
that the early malloc region, global data (gd), and early stack usage
|
||||
do not overlap any appended DTB.
|
||||
|
||||
config LINUX_KERNEL_IMAGE_HEADER
|
||||
bool
|
||||
help
|
||||
Place a Linux kernel image header at the start of the U-Boot binary.
|
||||
The format of the header is described in the Linux kernel source at
|
||||
Documentation/arm64/booting.txt. This feature is useful since the
|
||||
image header reports the amount of memory (BSS and similar) that
|
||||
U-Boot needs to use, but which isn't part of the binary.
|
||||
|
||||
if LINUX_KERNEL_IMAGE_HEADER
|
||||
config LNX_KRNL_IMG_TEXT_OFFSET_BASE
|
||||
hex
|
||||
help
|
||||
The value subtracted from CONFIG_SYS_TEXT_BASE to calculate the
|
||||
TEXT_OFFSET value written in to the Linux kernel image header.
|
||||
endif
|
||||
endif
|
||||
|
||||
config STATIC_RELA
|
||||
|
|
86
arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
Normal file
86
arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* (C) Copyright 2017 NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* Derived from Linux kernel v4.14 files:
|
||||
*
|
||||
* arch/arm64/include/asm/assembler.h:
|
||||
* Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
|
||||
* Copyright (C) 1996-2000 Russell King
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*
|
||||
* arch/arm64/kernel/head.S:
|
||||
* Based on arch/arm/kernel/head.S
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (C) 2003-2012 ARM Ltd.
|
||||
* Authors: Catalin Marinas <catalin.marinas@arm.com>
|
||||
* Will Deacon <will.deacon@arm.com>
|
||||
*
|
||||
* arch/arm64/kernel/image.h:
|
||||
* Copyright (C) 2014 ARM Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* There aren't any ELF relocations we can use to endian-swap values known only
|
||||
* at link time (e.g. the subtraction of two symbol addresses), so we must get
|
||||
* the linker to endian-swap certain values before emitting them.
|
||||
*
|
||||
* Note that, in order for this to work when building the ELF64 PIE executable
|
||||
* (for KASLR), these values should not be referenced via R_AARCH64_ABS64
|
||||
* relocations, since these are fixed up at runtime rather than at build time
|
||||
* when PIE is in effect. So we need to split them up in 32-bit high and low
|
||||
* words.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define DATA_LE32(data) \
|
||||
((((data) & 0x000000ff) << 24) | \
|
||||
(((data) & 0x0000ff00) << 8) | \
|
||||
(((data) & 0x00ff0000) >> 8) | \
|
||||
(((data) & 0xff000000) >> 24))
|
||||
#else
|
||||
#define DATA_LE32(data) ((data) & 0xffffffff)
|
||||
#endif
|
||||
|
||||
#define DEFINE_IMAGE_LE64(sym, data) \
|
||||
sym##_lo32 = DATA_LE32((data) & 0xffffffff); \
|
||||
sym##_hi32 = DATA_LE32((data) >> 32)
|
||||
|
||||
#define __MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define __CODE_DATA_SIZE (__bss_start - _start)
|
||||
#define __BSS_SIZE (__bss_end - __bss_start)
|
||||
#ifdef CONFIG_SYS_INIT_SP_BSS_OFFSET
|
||||
#define __MAX_EXTRA_RAM_USAGE __MAX(__BSS_SIZE, CONFIG_SYS_INIT_SP_BSS_OFFSET)
|
||||
#else
|
||||
#define __MAX_EXTRA_RAM_USAGE __BSS_SIZE
|
||||
#endif
|
||||
#define __MEM_USAGE (__CODE_DATA_SIZE + __MAX_EXTRA_RAM_USAGE)
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define __HEAD_FLAG_BE 1
|
||||
#else
|
||||
#define __HEAD_FLAG_BE 0
|
||||
#endif
|
||||
|
||||
#define __HEAD_FLAG_PAGE_SIZE 1 /* 4K hard-coded */
|
||||
|
||||
#define __HEAD_FLAG_PHYS_BASE 1
|
||||
|
||||
#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \
|
||||
(__HEAD_FLAG_PAGE_SIZE << 1) | \
|
||||
(__HEAD_FLAG_PHYS_BASE << 3))
|
||||
|
||||
#define TEXT_OFFSET (CONFIG_SYS_TEXT_BASE - \
|
||||
CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE)
|
||||
|
||||
/*
|
||||
* These will output as part of the Image header, which should be little-endian
|
||||
* regardless of the endianness of the kernel. While constant values could be
|
||||
* endian swapped in head.S, all are done here for consistency.
|
||||
*/
|
||||
#define HEAD_SYMBOLS \
|
||||
DEFINE_IMAGE_LE64(_kernel_size_le, __MEM_USAGE); \
|
||||
DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \
|
||||
DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
|
||||
|
||||
HEAD_SYMBOLS
|
|
@ -19,7 +19,9 @@
|
|||
|
||||
.globl _start
|
||||
_start:
|
||||
#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
#if defined(LINUX_KERNEL_IMAGE_HEADER)
|
||||
#include <asm/boot0-linux-kernel-header.h>
|
||||
#elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
|
||||
/*
|
||||
* Various SoCs need something special and SoC-specific up front in
|
||||
* order to boot, allow them to set that in their boot0.h file and then
|
||||
|
|
|
@ -159,4 +159,8 @@ SECTIONS
|
|||
/DISCARD/ : { *(.plt*) }
|
||||
/DISCARD/ : { *(.interp*) }
|
||||
/DISCARD/ : { *(.gnu*) }
|
||||
|
||||
#ifdef CONFIG_LINUX_KERNEL_IMAGE_HEADER
|
||||
#include "linux-kernel-image-header-vars.h"
|
||||
#endif
|
||||
}
|
||||
|
|
49
arch/arm/include/asm/boot0-linux-kernel-header.h
Normal file
49
arch/arm/include/asm/boot0-linux-kernel-header.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* (C) Copyright 2017 NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* Derived from Linux kernel v4.14 files:
|
||||
*
|
||||
* arch/arm64/include/asm/assembler.h:
|
||||
* Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
|
||||
* Copyright (C) 1996-2000 Russell King
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*
|
||||
* arch/arm64/kernel/head.S:
|
||||
* Based on arch/arm/kernel/head.S
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (C) 2003-2012 ARM Ltd.
|
||||
* Authors: Catalin Marinas <catalin.marinas@arm.com>
|
||||
* Will Deacon <will.deacon@arm.com>
|
||||
*
|
||||
* arch/arm64/kernel/image.h:
|
||||
* Copyright (C) 2014 ARM Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Emit a 64-bit absolute little endian symbol reference in a way that
|
||||
* ensures that it will be resolved at build time, even when building a
|
||||
* PIE binary. This requires cooperation from the linker script, which
|
||||
* must emit the lo32/hi32 halves individually.
|
||||
*/
|
||||
.macro le64sym, sym
|
||||
.long \sym\()_lo32
|
||||
.long \sym\()_hi32
|
||||
.endm
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
/*
|
||||
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
|
||||
*/
|
||||
b reset /* branch to kernel start, magic */
|
||||
.long 0 /* reserved */
|
||||
le64sym _kernel_offset_le /* Image load offset from start of RAM, little-endian */
|
||||
le64sym _kernel_size_le /* Effective size of kernel image, little-endian */
|
||||
le64sym _kernel_flags_le /* Informative flags, little-endian */
|
||||
.quad 0 /* reserved */
|
||||
.quad 0 /* reserved */
|
||||
.quad 0 /* reserved */
|
||||
.ascii "ARM\x64" /* Magic number */
|
||||
.long 0 /* reserved */
|
Loading…
Reference in a new issue