1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:48:11 +00:00

Kernel: Introduce basic pre-kernel environment

This implements a simple bootloader that is capable of loading ELF64
kernel images. It does this by using QEMU/GRUB to load the kernel image
from disk and pass it to our bootloader as a Multiboot module.

The bootloader then parses the ELF image and sets it up appropriately.
The kernel's entry point is a C++ function with architecture-native
code.

Co-authored-by: Liav A <liavalb@gmail.com>
This commit is contained in:
Gunnar Beutner 2021-07-18 14:47:32 +02:00 committed by Andreas Kling
parent 357ddd393e
commit 7e94b090fe
30 changed files with 1207 additions and 181 deletions

View file

@ -39,6 +39,7 @@
#include <Kernel/Net/NetworkTask.h>
#include <Kernel/Net/NetworkingManagement.h>
#include <Kernel/Panic.h>
#include <Kernel/Prekernel/BootInfo.h>
#include <Kernel/Process.h>
#include <Kernel/ProcessExposed.h>
#include <Kernel/RTC.h>
@ -77,7 +78,6 @@ extern "C" u8* end_of_kernel_image;
multiboot_module_entry_t multiboot_copy_boot_modules_array[16];
size_t multiboot_copy_boot_modules_count;
extern "C" const char kernel_cmdline[4096];
READONLY_AFTER_INIT bool g_in_early_boot;
namespace Kernel {
@ -89,7 +89,7 @@ static void setup_serial_debug();
// We declare them here to ensure their signatures don't accidentally change.
extern "C" void init_finished(u32 cpu) __attribute__((used));
extern "C" [[noreturn]] void init_ap(FlatPtr cpu, Processor* processor_info);
extern "C" [[noreturn]] void init();
extern "C" [[noreturn]] void init(BootInfo const&);
READONLY_AFTER_INIT VirtualConsole* tty0;
@ -105,11 +105,42 @@ static Processor s_bsp_processor; // global but let's keep it "private"
// Once multi-tasking is ready, we spawn a new thread that starts in the
// init_stage2() function. Initialization continues there.
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init()
extern "C" {
u8 const* start_of_bootloader_image;
u8 const* end_of_bootloader_image;
__attribute__((section(".boot_bss"))) FlatPtr kernel_base;
#if ARCH(X86_64)
extern "C" u32 gdt64ptr;
extern "C" u16 code64_sel;
FlatPtr boot_pml4t;
#endif
FlatPtr boot_pdpt;
FlatPtr boot_pd0;
FlatPtr boot_pd_kernel;
FlatPtr boot_pd_kernel_pt1023;
const char* kernel_cmdline;
}
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
{
g_in_early_boot = true;
setup_serial_debug();
multiboot_info_ptr = boot_info.multiboot_info_ptr;
start_of_bootloader_image = boot_info.start_of_prekernel_image;
end_of_bootloader_image = boot_info.end_of_prekernel_image;
kernel_base = boot_info.kernel_base;
#if ARCH(X86_64)
gdt64ptr = boot_info.gdt64ptr;
code64_sel = boot_info.code64_sel;
boot_pml4t = boot_info.boot_pml4t;
#endif
boot_pdpt = boot_info.boot_pdpt;
boot_pd0 = boot_info.boot_pd0;
boot_pd_kernel = boot_info.boot_pd_kernel;
boot_pd_kernel_pt1023 = boot_info.boot_pd_kernel_pt1023;
kernel_cmdline = boot_info.kernel_cmdline;
// We need to copy the command line before kmalloc is initialized,
// as it may overwrite parts of multiboot!
CommandLine::early_initialize(kernel_cmdline);