[lkrn] Add basic support for the RISC-V Linux kernel image format

The RISC-V and AArch64 bare-metal kernel images share a common header
format, and require essentially the same execution environment: loaded
close to the start of RAM, entered with paging disabled, and passed a
pointer to a flattened device tree that describes the hardware and any
boot arguments.

Implement basic support for executing bare-metal RISC-V and AArch64
kernel images.  The (trivial) AArch64-specific code path is untested
since we do not yet have the ability to build for any bare-metal
AArch64 platforms.  Constructing and passing an initramfs image is not
yet supported.

Rename the IMAGE_BZIMAGE build configuration option to IMAGE_LKRN,
since "bzImage" is specific to x86.  To retain backwards compatibility
with existing local build configurations, we leave IMAGE_BZIMAGE as
the enabled option in config/default/pcbios.h and treat IMAGE_LKRN as
a synonym for IMAGE_BZIMAGE when building for x86 BIOS.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-05-20 00:26:08 +01:00
parent d0c35b6823
commit ecac4a34c7
10 changed files with 460 additions and 1 deletions

View File

@@ -0,0 +1,30 @@
#ifndef _BITS_LKRN_H
#define _BITS_LKRN_H
/** @file
*
* Linux kernel image invocation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Header magic value */
#define LKRN_MAGIC_ARCH LKRN_MAGIC_AARCH64
/**
* Jump to kernel entry point
*
* @v entry Kernel entry point
* @v fdt Device tree
*/
static inline __attribute__ (( noreturn )) void
lkrn_jump ( physaddr_t entry, physaddr_t fdt ) {
register unsigned long x0 asm ( "x0" ) = fdt;
__asm__ __volatile__ ( "br %1"
: : "r" ( x0 ), "r" ( entry ) );
__builtin_unreachable();
}
#endif /* _BITS_LKRN_H */

View File

@@ -0,0 +1,34 @@
#ifndef _BITS_LKRN_H
#define _BITS_LKRN_H
/** @file
*
* Linux kernel image invocation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/hart.h>
/** Header magic value */
#define LKRN_MAGIC_ARCH LKRN_MAGIC_RISCV
/**
* Jump to kernel entry point
*
* @v entry Kernel entry point
* @v fdt Device tree
*/
static inline __attribute__ (( noreturn )) void
lkrn_jump ( physaddr_t entry, physaddr_t fdt ) {
register unsigned long a0 asm ( "a0" ) = boot_hart;
register unsigned long a1 asm ( "a1" ) = fdt;
__asm__ __volatile__ ( "call disable_paging\n\t"
"jr %2\n\t"
: : "r" ( a0 ), "r" ( a1 ), "r" ( entry ) );
__builtin_unreachable();
}
#endif /* _BITS_LKRN_H */