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;
 }