Guest User

Untitled

a guest
Aug 7th, 2020
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.40 KB | None | 0 0
  1. // Bootloader
  2. #include <efi.h>
  3. #include <efilib.h>
  4. #include <utils.h>
  5.  
  6. #include <pe_types.h>
  7. #include "bootinfo.h"
  8.  
  9. #define bfunc(func, msg)  s = func;               \
  10.                           if (s != EFI_SUCCESS) { \
  11.                             berror(msg, s);       \
  12.                           }
  13.  
  14. #define putline Print(L"%d\r\n", __LINE__)
  15.  
  16. #define berror(msg, status)  Print(msg);                               \
  17.                              Print(L"EFI error code: %r\r\n", status); \
  18.                              return status;
  19.  
  20. EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle,
  21.     EFI_SYSTEM_TABLE* SystemTable) {
  22.     InitializeLib(ImageHandle, SystemTable);
  23.     Print(L"Welcome to The Vegan OS\r\n");
  24.     Print(L"Starting boot sequence\r\n");
  25.     Print(L"Finding graphics modes\r\n");
  26.     EFI_STATUS s;
  27.  
  28. //==========Get graphics modes===========
  29.     EFI_GRAPHICS_OUTPUT_PROTOCOL* graphP;
  30.     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* graphInfo;
  31.     UINTN handleCount = 0;
  32.     EFI_HANDLE* graphBuf;
  33.     EFI_GUID graphGUID = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  34.     bfunc(SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &graphGUID, NULL, &handleCount, &graphBuf), L"Failed to locate handle buffer\r\n");
  35.     bfunc(SystemTable->BootServices->HandleProtocol(graphBuf[0], &graphGUID, (VOID **)&graphP), L"Failed to handle protocol\r\n");
  36.     UINTN modeNum;
  37.     UINTN sizeOfInfo;
  38.     UINT32 bestMode = 0, hHres = 0, hVres = 0;
  39.  
  40.     for (modeNum = 0; (s = graphP->QueryMode(graphP, modeNum, &sizeOfInfo, &graphInfo)) == EFI_SUCCESS; modeNum++) {
  41.         if (graphInfo->HorizontalResolution > hHres && graphInfo->VerticalResolution > hVres && graphInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor){
  42.             bestMode = modeNum;
  43.             hHres = graphInfo->HorizontalResolution;
  44.             hVres = graphInfo->VerticalResolution;
  45.             break;
  46.         }
  47.     }
  48.     Print(L"Found best graphics mode: %d with resolution %d x %d. Pixels per scan line: %d\r\n", bestMode, hHres, hVres, graphInfo->PixelsPerScanLine);
  49.  
  50.     EFI_FILE* kernel;
  51.  
  52.     //==========Open kernel binary==========
  53.     {
  54.         EFI_GUID gLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
  55.         EFI_GUID gSimpleFileSystemProtocol = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
  56.  
  57.         EFI_HANDLE_PROTOCOL HandleProtocol =
  58.             SystemTable->BootServices->HandleProtocol;
  59.         EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
  60.         bfunc(HandleProtocol(ImageHandle, &gLoadedImageProtocol,
  61.             (void**)&LoadedImage),
  62.             L"Failed to load image\r\n");
  63.  
  64.         EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileSystem;
  65.         bfunc(HandleProtocol(LoadedImage->DeviceHandle, &gSimpleFileSystemProtocol,
  66.             (void**)&FileSystem),
  67.             L"Failed to load filesystem\r\n");
  68.  
  69.         EFI_FILE_PROTOCOL* Root;
  70.         bfunc(FileSystem->OpenVolume(FileSystem, &Root),
  71.             L"Failed to load root directory\r\n");
  72.  
  73.         bfunc(Root->Open(Root, &kernel, L"kernel.exe", EFI_FILE_MODE_READ,
  74.             EFI_FILE_READ_ONLY),
  75.             L"Failed to load kernel binary\r\n");
  76.  
  77.         Print(L"Kernel binary successfully found\r\n");
  78.     }
  79.     //==========Parse kernel binary==========. Do not do anything after so not to mess up memory
  80.  
  81.     IMAGE_DOS_HEADER dosHdr;
  82.  
  83.     UINTN size = sizeof(IMAGE_DOS_HEADER);
  84.     kernel->Read(kernel, &size, &dosHdr);
  85.  
  86.     if (dosHdr.e_magic != 23117) {
  87.         Print(L"Incorrect magic number: %d\r\n", dosHdr.e_magic);
  88.     }
  89.  
  90.     kernel->SetPosition(kernel, dosHdr.e_lfanew);
  91.  
  92.     IMAGE_FILE_HEADER fileHeader;
  93.     size = sizeof(IMAGE_FILE_HEADER);
  94.     kernel->Read(kernel, &size, &fileHeader);
  95.     if (fileHeader.Signature != 17744) {
  96.         Print(L"Incorrect signature: %d\r\n", fileHeader.Signature);
  97.         berror(L"Bad signature\r\n", -1);
  98.     }
  99.     if (fileHeader.Machine != IMAGE_FILE_MACHINE_X64) {
  100.         Print(L"Kernel binary is incorrect machine type: %d", fileHeader.Machine);
  101.         berror(L"Bad machine type\r\n", -1);
  102.     }
  103.  
  104.     UINTN sizeOfOptHdr = (UINTN)fileHeader.SizeOfOptionalHeader;
  105.  
  106.     IMAGE_OPTIONAL_HEADER optHdr;
  107.     kernel->Read(kernel, &sizeOfOptHdr, &optHdr);
  108.  
  109.     if (optHdr.Magic != 0x20b) {
  110.         if (optHdr.Magic == 0x10b)
  111.             Print(L"Kernel binary is PE32 and will not be read properly.\r\n");
  112.         else
  113.             Print(L"Kernel binary has corrupted or incorrect magic number: %d\r\n",
  114.                 optHdr.Magic);
  115.         berror(L"Incorrect magic number\r\n", -1);
  116.     }
  117.  
  118.     Print(L"Kernel executable is not faulty and is of the correct types\r\n");
  119.     kernel->SetPosition(kernel, 0);
  120.     kernel->Read(kernel, &optHdr.SizeOfImage, (UINT64*) optHdr.ImageBase);
  121.     UINT64 entry = optHdr.ImageBase + optHdr.AddressOfEntryPoint;
  122.     Print(L"Kernel loaded at %x\r\n", entry);
  123.     Print(L"Jumping to kernel\r\n");
  124.     SystemTable->ConOut->ClearScreen(SystemTable->ConOut);
  125.     bfunc(graphP->SetMode(graphP, bestMode), L"Failed to set graphics mode\r\n");
  126.     //Exit boot services and jump to kernel
  127.     // Get memory map
  128.     EFI_MEMORY_DESCRIPTOR map;
  129.     UINTN mapSize, mapKey;
  130.     UINTN descriptorSize;
  131.     UINT32 descriptorVersion;
  132.  
  133.     EFI_GET_MEMORY_MAP GetMemoryMap = SystemTable->BootServices->GetMemoryMap;
  134.     GetMemoryMap(&mapSize, &map, &mapKey, &descriptorSize, &descriptorVersion);
  135.  
  136.     s = SystemTable->BootServices->ExitBootServices(ImageHandle, mapKey);
  137.     if (s != EFI_SUCCESS) {
  138.         //TODO: Jump back to text mode and say failed
  139.         Print(L"Failed to exit boot services. EFI: %r\r\n", s);
  140.         Pause();
  141.     }
  142.     else {
  143.         UINT32* at = (UINT32*)graphP->Mode->FrameBufferBase;
  144.         UINT32 col = 0x00ff99ff;
  145.         for (unsigned i = 0; i < 500000; i++)
  146.             *at++ = col;
  147.         BOOTINFO bootinfo = { SystemTable->RuntimeServices, &map, graphInfo, graphP->Mode->FrameBufferBase };
  148.         typedef VOID(__stdcall* kEntryPoint) (BOOTINFO* b);
  149.         kEntryPoint kernel_main = (kEntryPoint)entry;
  150.         kernel_main(&bootinfo);
  151.     }
  152.  
  153.     return EFI_SUCCESS;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment