changeset 3:c2a38c3c71ab

fix bootloader.c
author kono
date Fri, 19 Jan 2024 10:09:02 +0900
parents 4cca1b408702
children cc535678286d
files gnu-efi-3.0.12/apps/bootloader.c
diffstat 1 files changed, 127 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/gnu-efi-3.0.12/apps/bootloader.c	Tue Apr 11 12:18:17 2023 +0900
+++ b/gnu-efi-3.0.12/apps/bootloader.c	Fri Jan 19 10:09:02 2024 +0900
@@ -1,55 +1,143 @@
-#include<efi.h>
-#include<efilib.h>
+#include <efi.h>
+#include <efilib.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+struct __attribute__((packed)) BootParam {
+  UINT64 kernel_entry;
+  UINT64 rsdp_addr;
+  // struct GraphicConfig graphic_config;
+//  struct gdt bootstrap_gdt[3];
+//  struct gdt_desc bootstrap_gdt_desc;
+  UINT64 kernel_addr;
+};
+
+struct MemoryMap {
+  UINTN BufferSize;
+  VOID *Buffer;
+  UINTN MapSize;
+  UINTN MapKey;
+  UINTN DescriptorSize;
+  UINT32 DescriptorVersion;
+};
 
 
-EFI_STATUS
-efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
-{
-    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";
-    EFI_STATUS Status=EFI_SUCCESS;
+EFI_STATUS LoadFile(EFI_HANDLE ImageHandle, CHAR16 *FileName, EFI_PHYSICAL_ADDRESS *FileAddr, UINTN *FilePageSize) {
+    EFI_STATUS Status;
+    EFI_FILE_IO_INTERFACE *IOVolume;
+    EFI_FILE_HANDLE Root;
+    EFI_FILE_HANDLE File;
+    Print(L"LoadFile\n");
+
+    Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle, &FileSystemProtocol, (VOID **)&IOVolume);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to locate File System Protocol.\n");
+        return Status;
+    }
+
+    Status = uefi_call_wrapper(IOVolume->OpenVolume, 2, IOVolume, &Root);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to open volume.\n");
+        return Status;
+    }
+    Print(L"Loading File: %s\n", FileName);
 
-    InitializeLib(ImageHandle, SystemTable);
-    Print(L"Hello, EFI!\n");
+    Status = uefi_call_wrapper(Root->Open, 5, Root, &File, FileName, EFI_FILE_MODE_READ, 0);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to open %s\n", FileName);
+        return Status;
+    }
 
-    Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol,(void**)&LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+    EFI_FILE_INFO *FileInfo;
+    UINTN FileInfoSize;
+    FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;
+    FileInfo = AllocatePool(FileInfoSize);
+    Status = uefi_call_wrapper(File->GetInfo, 4, File, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);
     if (EFI_ERROR(Status)) {
-        Print(L"Could not get LoadedImageProtocol handler %r\n", Status);
+        Print(L"Failed to get file info.\n");
+        FreePool(FileInfo);
+        return Status;
+    }
+
+    UINTN FileSize = FileInfo->FileSize;
+    Print(L"FileSize = %d\n", FileSize);
+    *FilePageSize = (FileSize + 4095) / 4096;
+    *FileAddr = 0;
+    Status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData, *FilePageSize, FileAddr);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to allocate pages.\n");
+        FreePool(FileInfo);
         return Status;
     }
-    Print(L"Hello,2!\n");
-    Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\OS");
-    if (Path == NULL) {
-        Print(L"Could not get device path.");
-        return EFI_INVALID_PARAMETER;
+
+    Status = uefi_call_wrapper(File->Read, 3, File, &FileSize, (VOID *)*FileAddr);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to load file.\n");
+        FreePool(FileInfo);
+        return Status;
     }
-    Print(L"Hello,3!\n");
-    Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image);
+    Print(L"Successfully loaded file: %s\n", FileName);
+
+    FreePool(FileInfo);
+    return Status;
+}
+
+EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
+
+    EFI_STATUS Status;
+    CHAR16 *KernelFileName = L"\\kernel";
+    EFI_PHYSICAL_ADDRESS KernelBaseAddr;
+
+    InitializeLib(ImageHandle, SystemTable);
+    Print(L"Initializeing\n");
+    UINTN BufferPageSize;
+    Print(L"LoadFile: %s\n", KernelFileName);
+    Status = LoadFile(ImageHandle, KernelFileName, &KernelBaseAddr, &BufferPageSize);
     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);
+
+    struct BootParam boot_param;
+    boot_param.kernel_addr = KernelBaseAddr;
+    boot_param.kernel_entry = KernelBaseAddr;
+    // GetGraphicMode(ImageHandle, &(boot_param.graphic_config));
+
+    typedef unsigned long (EntryPoint)(struct BootParam*);
+    EntryPoint *Entry = (EntryPoint*)(KernelBaseAddr);
+
+    // VOID *vendor_table;
+    // Status = SystemTable->BootServices->GetSystemConfigurationTable(&gEfiAcpiTableGuid, &vendor_table);
+    // if (EFI_ERROR(Status)) {
+    //     Print(L"Failed to get system configuration table.\n");
+    //     return Status;
+    // }
+    // boot_param.rsdp_addr = (UINT64)vendor_table;
+
+    struct MemoryMap MemoryMap = {4096, NULL, 4096, 0, 0, 0};
+    Status = uefi_call_wrapper(SystemTable->BootServices->AllocatePool, 3, EfiLoaderData, MemoryMap.BufferSize, &MemoryMap.Buffer);
     if (EFI_ERROR(Status)) {
-        Print(L"Could not get LoadedImageProtocol handler %r\n", Status);
-        uefi_call_wrapper(BS->UnloadImage, 1, Image);
-        FreePool(Path);
+        Print(L"Failed to allocate memory to get memory map\n");
         return Status;
     }
-    Print(L"Hello,5!\n");
-    LoadedImage->LoadOptions = Options;
-    LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16);
-    
-    Print(L"Hello,6!\n");
-    Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL);
-    uefi_call_wrapper(BS->UnloadImage, 1, Image);
-    FreePool(Path);
-    Print(L"Hello,7!\n");
+
+    Status = uefi_call_wrapper(SystemTable->BootServices->GetMemoryMap, 5, &MemoryMap.MapSize, (EFI_MEMORY_DESCRIPTOR*)MemoryMap.Buffer, &MemoryMap.MapKey, &MemoryMap.DescriptorSize, &MemoryMap.DescriptorVersion);
+    if (EFI_ERROR(Status)) {
+        Print(L"Failed to get memory map.\n");
+        return Status;
+    }
 
-    return EFI_SUCCESS;
+    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;
+    }
+
+    Entry(&boot_param);
+
+    return Status;
 }
+
+
+
+