arch/arm: Add support for loading Linux kernels

Adds support for loading Linux kernels through FIT payloads. This has
been implemented as an assembly function in order to simplify dealing
with some of the intricacies of loading a kernel (such as needing to
jump to the kernel in ARM mode and the kernel ABI).

TEST: Booted a FIT image containing a 5.4 kernel and initramfs on the
Beaglebone Black.

Change-Id: I7dbf9467665ec17447cec73676763844b4be4764
Signed-off-by: Sam Lewis <sam.vr.lewis@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45335
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Sam Lewis 2020-09-14 21:04:35 +10:00 committed by Patrick Georgi
parent d5dda47db8
commit 362a156867
3 changed files with 42 additions and 2 deletions

View File

@ -119,6 +119,7 @@ ramstage-y += memset.S
ramstage-y += memcpy.S
ramstage-y += memmove.S
ramstage-y += clock.c
ramstage-y += boot_linux.S
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
rmodules_arm-y += memset.S

View File

@ -1,14 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <cbfs.h>
#include <arch/cache.h>
#include <program_loading.h>
void boot_linux(void *kernel_ptr, void *fdt_ptr);
void arch_prog_run(struct prog *prog)
{
void (*doit)(void *);
cache_sync_instructions();
doit = prog_entry(prog);
doit(prog_entry_arg(prog));
switch (prog_cbfs_type(prog)) {
case CBFS_TYPE_FIT:
/*
* We only load Linux payloads from the ramstage, so provide a hint to
* the linker that the below functions do not need to be included in
* earlier stages.
*/
if (!ENV_RAMSTAGE)
break;
dcache_mmu_disable();
boot_linux(prog_entry(prog), prog_entry_arg(prog));
break;
default:
doit = prog_entry(prog);
doit(prog_entry_arg(prog));
}
}

21
src/arch/arm/boot_linux.S Normal file
View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/asm.h>
/* Required to jump to kernel in ARM state */
.arm
/* void boot_linux(void *kernel_ptr, void *fdt_ptr); */
ENTRY(boot_linux)
/* Save kernel ptr */
mov r3, r0
/* Set R2 = fdt */
mov r2, r1
/* Set R0 = 0x00000000 as expected by Linux ABI */
mov r0, #0
/* Set R1 = 0xffffffff as expected by Linux ABI */
mov r1, #-1
/* Linux ABI expects SVC mode (0x13) with IRQ(7) and FIQ(6) disabled. */
msr cpsr_cxf, #0xd3
/* Jump to kernel */
mov pc, r3
ENDPROC(boot_linux)