blob: 9e602a71d5a4d4683ac8f19c731fea0142c71ed0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
// ============================================================================
// aarch64/entry.cpp - UEFI entry point for AArch64
//
// Kernel entry point: extern "C" [[noreturn]] void kernel_main(BootInfo*);
// Chain: UEFI -> efi_main -> jumps to _start (entry.S) -> calls kernel_main (from kernel_main.cpp)
// Why we need to run asm code:
// Because we haven't stack pointer, that needed for c/c++
// In efi_main / efi_loader_main we have it, because UEFI setup it for us
// ============================================================================
#include <boot/efi.h>
#include <boot/boot_info.h>
extern bool efi_loader_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE* system_table, BootInfo* boot_info);
static BootInfo g_boot_info{};
typedef void (*KernelEntry)(BootInfo*); // _start
extern "C" EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE* system_table) {
if (!efi_loader_main(image_handle, system_table, &g_boot_info))
return EFI_LOAD_ERROR;
/*
entry_offset - how far the entry point is from the start of the kernel image.
For example if kernel_entry_point is 0x100000 and kernel_virt_base is 0x100000, the offset is 0
phys_entry - the actual physical address to jump to: kernel_phys_base + entry_offset
*/
uint64_t entry_offset = g_boot_info.kernel_entry_point - g_boot_info.kernel_virt_base;
uint64_t phys_entry = g_boot_info.kernel_phys_base + entry_offset;
auto kernel_entry = reinterpret_cast<KernelEntry>(phys_entry);
kernel_entry(&g_boot_info); // X0 = &g_boot_info (AAPCS64)
for (;;) asm volatile("wfi");
}
|