Mercurial > hg > Gears > UEFIloader
changeset 9:33d10c470c6e default tip
now it works.
author | kono |
---|---|
date | Sat, 20 Jan 2024 16:13:18 +0900 |
parents | c4198b641a84 |
children | |
files | gnu-efi-3.0.12/apps/bootloader.c |
diffstat | 1 files changed, 97 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/gnu-efi-3.0.12/apps/bootloader.c Fri Jan 19 17:30:15 2024 +0900 +++ b/gnu-efi-3.0.12/apps/bootloader.c Sat Jan 20 16:13:18 2024 +0900 @@ -106,7 +106,7 @@ Print(L"FileSize = %d\n", FileSize); *FilePageSize = (FileSize + 4095) / 4096; *FileAddr = 0x40000000; - Status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAddress, EfiLoaderData, *FilePageSize, FileAddr); + Status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAddress, EfiBootServicesCode, *FilePageSize, FileAddr); if (EFI_ERROR(Status)) { Print(L"Failed to allocate pages.\n"); FreePool(FileInfo); @@ -143,6 +143,37 @@ return Status; } +UINT64 ReadCurrentEL() { + UINT64 currentEL; + __asm__ volatile("MRS %0, CurrentEL" : "=r" (currentEL)); + return (currentEL >> 2) & 0x3; // Extract EL value +} + +void DumpLoadedImageProtocol(EFI_LOADED_IMAGE *LoadedImage) { + Print(L"Dumping EFI_LOADED_IMAGE_PROTOCOL\n"); + Print(L"Revision: %x\n", LoadedImage->Revision); + Print(L"ParentHandle: %x\n", LoadedImage->ParentHandle); + Print(L"SystemTable: %x\n", LoadedImage->SystemTable); + + Print(L"DeviceHandle: %x\n", LoadedImage->DeviceHandle); + Print(L"FilePath: %s\n", DevicePathToStr(LoadedImage->FilePath)); + // Note: LoadedImage->Reserved is not dumped as it's meant to be NULL/unused + + Print(L"LoadOptionsSize: %x\n", LoadedImage->LoadOptionsSize); + Print(L"LoadOptions: %s\n", LoadedImage->LoadOptions); + + Print(L"ImageBase: %x\n", LoadedImage->ImageBase); + Print(L"ImageSize: %lx\n", LoadedImage->ImageSize); + Print(L"ImageCodeType: %x\n", LoadedImage->ImageCodeType); + Print(L"ImageDataType: %x\n", LoadedImage->ImageDataType); + + if (LoadedImage->Unload != NULL) { + Print(L"Unload: %x\n", LoadedImage->Unload); + } else { + Print(L"Unload: NULL\n"); + } +} + EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS Status; @@ -166,8 +197,6 @@ boot_param.kernel_entry = boot_param.kernel_addr ; // GetGraphicMode(ImageHandle, &(boot_param.graphic_config)); - typedef unsigned long (EntryPoint)(struct BootParam*); - EntryPoint *Entry = (EntryPoint*)(KernelBaseAddr); Print(L"Boot 2\n"); @@ -204,14 +233,79 @@ HexDump((UINT8 *)KernelBaseAddr,0x100); + EFI_DEVICE_PATH *Path; + EFI_LOADED_IMAGE *LoadedImageParent; + EFI_LOADED_IMAGE *LoadedImage; + EFI_HANDLE Image; + CHAR16 *Options = L"root=/dev/sda2 rootfstype=btrfs rw quiet splash"; + + Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol,(void**)&LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + return Status; + } + Print(L"Hello,2!\n"); + if (0) { + Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\kernel"); + if (Path == NULL) { + Print(L"Could not get device path."); + return EFI_INVALID_PARAMETER; + } + Print(L"Hello,3!\n"); + Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); + if (EFI_ERROR(Status)) { + Print(L"Could not load %r", Status); + FreePool(Path); + return Status; + } + Print(L"Hello,4!\n"); + Status = uefi_call_wrapper(BS->OpenProtocol, 6, Image, &LoadedImageProtocol, (void**)&LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + return Status; + } + Print(L"Hello,5!\n"); + LoadedImage->LoadOptions = Options; + LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16); + + DumpLoadedImageProtocol (LoadedImage); + Status = uefi_call_wrapper(SystemTable->BootServices->ExitBootServices, 2, ImageHandle, MemoryMap.MapKey); if (EFI_ERROR(Status)) { Print(L"Failed to exit boot services\n"); return Status; } + // Start the image + Status = uefi_call_wrapper(SystemTable->BootServices->StartImage, 3, Image, NULL, NULL); + + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + + } else { + + UINT64 el = ReadCurrentEL(); + Print(L"Current Exception Level: %d\n", el); + + Status = uefi_call_wrapper(SystemTable->BootServices->ExitBootServices, 2, ImageHandle, MemoryMap.MapKey); + if (EFI_ERROR(Status)) { + Print(L"Failed to exit boot services\n"); + return Status; + + } + + + // Inline assembly to jump to the kernel + // __asm__ volatile("br %0" : : "r"(0x40000000)); + + typedef unsigned long (EntryPoint)(struct BootParam*); + EntryPoint *Entry = (EntryPoint*)(KernelBaseAddr); Entry(&boot_param); + } + return Status; }