Advertisement
Guest User

Untitled

a guest
Jun 21st, 2022
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.87 KB | None | 0 0
  1. #include <efi.h>
  2. #include <efilib.h>
  3. #include <stdbool.h>
  4.  
  5. #include "bootloader/elf_parse.h"
  6. #include "bootloader/fileops.h"
  7. #include "kernel/include/xtos.h"
  8.  
  9. #include "bootloader/efiConsoleControl.h"
  10.  
  11. EFI_STATUS
  12. get_memory_map(OUT void **map, OUT UINTN *mem_map_size, OUT UINTN *mem_map_key,
  13.                OUT UINTN *descriptor_size) {
  14.   EFI_STATUS status;
  15.   *mem_map_size = sizeof(EFI_MEMORY_DESCRIPTOR) * 48;
  16.   UINTN mem_map_descriptor_version;
  17.  
  18.   // Keep trying larger buffers until we find one large enough to hold the map
  19.   while (1) {
  20.     status = uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData,
  21.                                *mem_map_size, map);
  22.  
  23.     if (EFI_ERROR(status)) {
  24.       Print(L"AllocatePool() error: %d (tried to allocate %d bytes)\n", status,
  25.             *mem_map_size);
  26.       return status;
  27.     }
  28.  
  29.     Print(L"Trying to get memory map with size: %d, buffer: %x...\n",
  30.           *mem_map_size, *map);
  31.     status =
  32.         uefi_call_wrapper(BS->GetMemoryMap, 5, mem_map_size, *map, mem_map_key,
  33.                           descriptor_size, &mem_map_descriptor_version);
  34.  
  35.     // We can only recover from an EFI_BUFFER_TOO_SMALL error
  36.     if (status == EFI_BUFFER_TOO_SMALL) {
  37.       /*
  38.         `mem_map_size` will point to the size needed if the previous call failed
  39.         but we want to reserve a bit more space than we needed for the last
  40.         call in case the new allocation changed the memory map.
  41.       */
  42.       Print(L"%d %d %d\n", *mem_map_key, *map, *mem_map_size);
  43.       status = uefi_call_wrapper(BS->FreePool, 1, *map);
  44.       *mem_map_size += sizeof(EFI_MEMORY_DESCRIPTOR) * 16;
  45.     } else {
  46.       return status;  // It's up to caller to check for an error
  47.     }
  48.   }
  49. }
  50.  
  51. void wait_for_keypress() {
  52.   UINTN event_index;
  53.   EFI_EVENT events[1] = {ST->ConIn->WaitForKey};
  54.   uefi_call_wrapper(BS->WaitForEvent, 3, 1, events, &event_index);
  55. }
  56.  
  57. bool guids_match(EFI_GUID guid1, EFI_GUID guid2) {
  58.   bool first_part_good =
  59.       (guid1.Data1 == guid2.Data1 && guid1.Data2 == guid2.Data2 &&
  60.        guid1.Data3 == guid2.Data3);
  61.  
  62.   if (!first_part_good) return false;
  63.  
  64.   for (int i = 0; i < 8; ++i) {
  65.     if (guid1.Data4[i] != guid2.Data4[i]) return false;
  66.   }
  67.  
  68.   return true;
  69. }
  70.  
  71. EFI_GUID gEfiConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
  72.  
  73. EFI_STATUS
  74. EFIAPI
  75. efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
  76.   EFI_STATUS status;
  77.  
  78.   InitializeLib(ImageHandle, SystemTable);
  79.  
  80.   uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL);
  81.   uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, FALSE);
  82.  
  83.   EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
  84.  
  85.   if (uefi_call_wrapper(BS->LocateProtocol, 3, &gEfiConsoleControlProtocolGuid,
  86.                         NULL, &ConsoleControl) == EFI_SUCCESS) {
  87.     uefi_call_wrapper(ConsoleControl->SetMode, 2, ConsoleControl,
  88.                       EfiConsoleControlScreenText);
  89.   }
  90.  
  91.   fops_init(ImageHandle);
  92.  
  93.   // Load the kernel ELF file into memory and get the entry address
  94.   void *kernel_main_addr = NULL;
  95.   status = load_kernel(L"kernel", &kernel_main_addr);
  96.   if (status != EFI_SUCCESS) {
  97.     Print(L"Error loading kernel: %d\n", status);
  98.     return EFI_ABORTED;
  99.   }
  100.  
  101.   Print(L"Got kernel_main at: 0x%x\n", kernel_main_addr);
  102.  
  103.   EFI_CONFIGURATION_TABLE *configuration_tables =
  104.       SystemTable->ConfigurationTable;
  105.  
  106.   void *xdsp_address = NULL;
  107.   static EFI_GUID acpi_guid = ACPI_20_TABLE_GUID;
  108.   for (unsigned i = 0; i < SystemTable->NumberOfTableEntries; ++i) {
  109.     if (guids_match(acpi_guid, configuration_tables[i].VendorGuid)) {
  110.       Print(L"Found ACPI Table pointer 0x%x\n",
  111.             configuration_tables[i].VendorTable);
  112.       xdsp_address = configuration_tables[i].VendorTable;
  113.     }
  114.   }
  115.  
  116.   if (!xdsp_address) {
  117.     Print(L"Could not locate ACPI v2.0 table, aborting!\n");
  118.     return EFI_ABORTED;
  119.   }
  120.  
  121.   // Get access to a simple graphics buffer
  122.   // Try to close graphic version
  123.   EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
  124.   EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  125.  
  126.   UINTN BufferSize = 0;
  127.   EFI_HANDLE *HandleBuffer = NULL;
  128.   status = uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol, &gop_guid, NULL, &BufferSize, &HandleBuffer);
  129.   if (EFI_ERROR(status)) {
  130.     Print(
  131.       L"Could not locate Simple Graphics Output Protocol handle, error: %d. "
  132.       L"Aborting.\n",
  133.       status);
  134.     return EFI_ABORTED;
  135.   }
  136.   status = uefi_call_wrapper(BS->HandleProtocol, 3, HandleBuffer[0], &gop_guid, &gop);
  137.   if (EFI_ERROR(status)) {
  138.     Print(
  139.       L"Could not handle Simple Graphics Output Protocol, error: %d. "
  140.       L"Aborting.\n",
  141.       status);
  142.     return EFI_ABORTED;
  143.   }
  144.  
  145.   UINT32 max_mode = gop->Mode->MaxMode;
  146.   Print(L"Current mode: %d, max mode: %d\n", gop->Mode->Mode, max_mode);
  147.  
  148.   // uefi_call_wrapper(gop->SetMode, 2, gop, max_mode-2);
  149.  
  150.   // Wait for keypress to give us time to attach a debugger, etc.
  151.   // Print(L"Waiting for keypress to continue booting...\n");
  152.   // wait_for_keypress();
  153.  
  154.   // Get memory map
  155.   UINTN mem_map_size = 0, mem_map_key = 0, mem_map_descriptor_size = 0;
  156.   uint8_t *mem_map = NULL;
  157.  
  158.   // Try to exit boot services 3 times
  159.   for (int retries = 0; retries < 3; ++retries) {
  160.     status = get_memory_map((void **)&mem_map, &mem_map_size, &mem_map_key,
  161.                             &mem_map_descriptor_size);
  162.  
  163.     if (EFI_ERROR(status)) {
  164.       Print(L"Error getting memory map!\n");
  165.       return status;
  166.     }
  167.  
  168.     //Try to load protocol infomation
  169.     //EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *EntryArray;
  170.     //status = uefi_call_wrapper(BS->OpenProtocolInformation, 4, HandleBuffer[0], &gop_guid, &EntryArray, NULL);
  171.     //if (EFI_ERROR(status)) {
  172.     //  Print(L"Error getting infomation of gop!\n");
  173.     //  return status;
  174.     //}
  175.     Print(L"?\n");
  176.    
  177.     //status = uefi_call_wrapper(BS->CloseProtocol, 4, HandleBuffer[0], &gop_guid, EntryArray->AgentHandle, EntryArray->ControllerHandle);
  178.     //if (EFI_ERROR(status)) {
  179.     //  Print(L"Error closing gop!\n");
  180.     //  return status;
  181.     //}
  182.     // Exit boot services
  183.     status =
  184.         uefi_call_wrapper(BS->ExitBootServices, 2, ImageHandle, mem_map_key);
  185.     // Execute kernel if we are successful
  186.     if (status == EFI_SUCCESS) {
  187.       // Jump to kernel code
  188.       KernelInfo info = {.xdsp_address = xdsp_address,
  189.                          .memory_map = mem_map,
  190.                          .mem_map_size = mem_map_size,
  191.                          .mem_map_descriptor_size = mem_map_descriptor_size,
  192.                          .gop = gop};
  193.       ((KernelMainFunc)kernel_main_addr)(info);
  194.     }
  195.   }
  196.  
  197.   /*
  198.     If we've reached here, we haven't managed to exit boot services,
  199.     we should print an error, free our resources and return.
  200.   */
  201.  
  202.   Print(L"Unable to successfully exit boot services. Last status: %d\n",
  203.         status);
  204.   uefi_call_wrapper(BS->FreePool, 1, mem_map);
  205.  
  206.   return EFI_ABORTED;
  207. }
  208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement