Mostly 0BSD-licensed RV64GC
Rust kernel for Qemu's virt
machine
Files not made by me (and possibly not 0BSD-licensed) are kernel/kernel_main/asm/trap.S
.
Based off my earlier project rust-0bsd-riscv-kernel
. I learnt some things from it, so this kernel is designed in a different way.
kernel/kernel_main
gets compiled withusize::MAX - 0x8000_0000
as its base address. This means that all kernel routines will think that they are located in the last0x8000_0000
bytes of memory.- The code in resulting ELF file gets dumped using
objcopy
intokernel_payload.bin
. The first byte is at virtual addressusize::MAX - 0x8000_0000
. This is done inlink.sh
kernel/kernel_bootloader
is compiled with its base address at0x8020_0000
. It usesinclude_bytes!
to includekernel_payload.bin
in its final binary.- qemu is launched, with the binary resulting from the compilation of
kernel_bootloader
as the kernel image.
- A platform bootloader runs. It loads the kernel image and puts it at physical address
0x8020_0000
. It also jumps to firmware code (OpenSBI). In our case, QEMU fulfills this role. - OpenSBI runs before the kernel. This is provided by the platform too.
- OpenSBI jumps to
0x8020_0000
. The code there is atkernel/kernel_bootloader/boot.S
. - The
pre_main
function is run. It sets up a small heap based on hardcoded memory addresses. It creates a page table where physical memory is mapped to the higher half of the virtual address space. - In addition,
pre_main
maps the kernel image in the same page table tousize::MAX - 0x8000_0000
. pre_main
jumps tousize::MAX - 0x8000_0000
. This iskernel_main::boot
, a naked function this time.- Rest of the kernel gets called by
kernel_main::boot
. TODO: Process execution and hart management