diff options
Diffstat (limited to 'kernel/head.S')
| -rw-r--r-- | kernel/head.S | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/head.S b/kernel/head.S index c8f523d..210eb7c 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -1,9 +1,61 @@ +#include <fbos/image.h> #include <fbos/mm.h> .global _start +.global _start_kernel .section .head.text +// Since this kernel boots in virtualization environments and machines that are +// expecting a Linux kernel, we have to adhere to how bootloaders expect Linux +// kernel images to look like. In particular, the entry of the kernel is +// actually a Boot image header, as defined in: +// +// https://docs.kernel.org/arch/riscv/boot-image-header.html +// +// Conveniently, for machines who don't care about this (e.g. QEMU), the first +// 64 bits correspond to two instructions that can be set up, and hence entering +// here will simply jumpt to `_start_kernel`, our real entry. _start: + // The first two words give us room for two executable instructions. Linux + // uses that on EFI support to first allocate a magic value for UEFI and + // then have a `j _start_kernel` instruction. Otherwise it just allocates + // the first one for `j _start_kernel` and leaves the second word empty. The + // latter is what we do here as well. + j _start_kernel + .word 0 + + // Ensure alignment for the next double word. + .balign 8 + + // Load offset. Note that this matches the PAGE_OFFSET as defined in + // `include/mm.h`. + .dword 0x200000 + + // Size of the image. This is *mandatory* as per bootloader request. + .dword _end - _start + + // Flags. As defined by Linux, only one bit matters here, which is related + // to endianness. Setting 0 means little-endian. + .dword 0 + + // Header version. + .word RISCV_HEADER_VERSION + + // Reserved fields. + .word 0 + .dword 0 + + // Deprecated image magic. + .ascii RISCV_IMAGE_MAGIC + .balign 4 + + // Good image magic, in little-endian format. + .ascii RISCV_IMAGE_MAGIC2 + + // Reserved field. + .word 0 + +_start_kernel: // Mask all interrupts csrw sie, zero csrw sip, zero |
