// ============================================================================ // 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 #include 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(phys_entry); kernel_entry(&g_boot_info); // X0 = &g_boot_info (AAPCS64) for (;;) asm volatile("wfi"); }