mirror of
https://git.checksum.fail/alec/templeos-uefi.git
synced 2026-05-26 17:49:58 +00:00
201 lines
4.9 KiB
C
201 lines
4.9 KiB
C
#include <Uefi.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/DevicePathLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/ShellCEntryLib.h>
|
|
#include <Library/ShellLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Protocol/LoadedImage.h>
|
|
#include <Protocol/LoadFile.h>
|
|
#include <Protocol/GraphicsOutput.h>
|
|
|
|
#include "stdlib.h"
|
|
|
|
#define CheckStatus(Status, Code) {\
|
|
if(EFI_ERROR(Status)){\
|
|
Print(L"Error: Status = %d, LINE=%d in %s\n", (Status), __LINE__, __func__);\
|
|
Code;\
|
|
}\
|
|
}
|
|
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
|
|
|
|
// Wrapper functions for TempleOS: UEFIGopBlt, MAlloc, Free, MSize
|
|
|
|
void tos_blt(void * ptr)
|
|
{
|
|
Gop->Blt(Gop, ptr, EfiBltBufferToVideo, 0, 0, 0, 0, 640, 480, 0);
|
|
}
|
|
|
|
void *tos_malloc(size_t s)
|
|
{
|
|
size_t * ret = malloc(sizeof(size_t) + s);
|
|
*ret = s;
|
|
return &ret[1];
|
|
}
|
|
|
|
void tos_free(void * ptr)
|
|
{
|
|
free( (size_t*)ptr - 1);
|
|
}
|
|
|
|
size_t tos_msize(void * ptr)
|
|
{
|
|
return ((size_t*)ptr)[-1];
|
|
}
|
|
// ********
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
LoadFileByName (
|
|
IN CONST CHAR16 *FileName,
|
|
OUT UINT8 **FileData,
|
|
OUT UINTN *FileSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SHELL_FILE_HANDLE FileHandle;
|
|
EFI_FILE_INFO *Info;
|
|
UINTN Size;
|
|
UINT8 *Data;
|
|
|
|
// Open File by shell protocol
|
|
Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
|
|
CheckStatus(Status, return (Status));
|
|
|
|
// Get File Info
|
|
Info = ShellGetFileInfo(FileHandle);
|
|
Size = (UINTN)Info->FileSize;
|
|
FreePool(Info);
|
|
|
|
// Allocate buffer to read file.
|
|
Data = AllocateRuntimeZeroPool(Size);
|
|
if (Data == NULL) {
|
|
Print(L"Error: AllocateRuntimeZeroPool failed\n");
|
|
return (EFI_OUT_OF_RESOURCES);
|
|
}
|
|
|
|
// Read file into Buffer
|
|
Status = ShellReadFile(FileHandle, &Size, Data);
|
|
CheckStatus(Status, return (Status));
|
|
|
|
// Close file
|
|
Status = ShellCloseFile(&FileHandle);
|
|
CheckStatus(Status, return (Status));
|
|
|
|
*FileSize = Size;
|
|
*FileData = Data;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
// Wrapper function for TempleOS: FileRead
|
|
|
|
void *tos_fileread(CHAR16 *FileName)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *FileData;
|
|
Status = LoadFileByName(FileName, &FileData, (UINTN *)0x3050);
|
|
CheckStatus(Status, return ((int *) - 1));
|
|
Print(L"FileRead: %s\n", FileName);
|
|
return &FileData[0];
|
|
}
|
|
|
|
INTN
|
|
EFIAPI
|
|
ShellAppMain (
|
|
IN UINTN Argc,
|
|
IN CHAR16 **Argv
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CHAR16 *FileName = L"Kernel.BIN.C";
|
|
UINTN FileSize;
|
|
UINT8 *FileData;
|
|
VOID *EntryPoint = NULL;
|
|
EFI_HANDLE *HandleBuffer = NULL;
|
|
UINTN HandleCount = 0;
|
|
BOOLEAN LowerHandle = FALSE;
|
|
|
|
|
|
// Load the file to buffer
|
|
Status = LoadFileByName(FileName, &FileData, &FileSize);
|
|
CheckStatus(Status, return (-1));
|
|
|
|
gST->ConOut->ClearScreen( gST->ConOut );
|
|
Print(L"TempleOS UEFI Boot Loader\n\n");
|
|
EntryPoint = (VOID *)0x7C00;
|
|
gBS->CopyMem(EntryPoint, FileData, FileSize);
|
|
Print(L"Loading Kernel.BIN.C\n");
|
|
|
|
|
|
|
|
// Try locating GOP by handle
|
|
Status = gBS->LocateHandleBuffer( ByProtocol,
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
NULL,
|
|
&HandleCount,
|
|
&HandleBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
Print(L"ERROR: No GOP handles found via LocateHandleBuffer\n");
|
|
} else {
|
|
Print(L"Found %d GOP handles via LocateHandleBuffer\n", HandleCount);
|
|
if (LowerHandle)
|
|
HandleCount = 0;
|
|
else
|
|
HandleCount--;
|
|
|
|
Status = gBS->OpenProtocol( HandleBuffer[HandleCount],
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
(VOID **)&Gop,
|
|
gImageHandle,
|
|
NULL,
|
|
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
|
if (EFI_ERROR (Status)) {
|
|
Print(L"ERROR: OpenProtocol [%d]\n", Status);
|
|
}
|
|
|
|
FreePool(HandleBuffer);
|
|
}
|
|
|
|
// Set Graphics Output Mode to 640x480x32
|
|
for (int i = 0; i < Gop->Mode->MaxMode; i++) {
|
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
|
|
UINTN SizeOfInfo;
|
|
|
|
Status = Gop->QueryMode(Gop, i, &SizeOfInfo, &Info);
|
|
if (EFI_ERROR(Status) && Status == EFI_NOT_STARTED) {
|
|
Gop->SetMode(Gop, Gop->Mode->Mode);
|
|
Status = Gop->QueryMode(Gop, i, &SizeOfInfo, &Info);
|
|
}
|
|
if (EFI_ERROR(Status)) {
|
|
continue;
|
|
}
|
|
if (Info->HorizontalResolution == 640 && Info->VerticalResolution == 480) {
|
|
{
|
|
Gop->SetMode(Gop, i);
|
|
};
|
|
}
|
|
}
|
|
|
|
// Clear Display
|
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL p;
|
|
p.Red = 0;
|
|
p.Green = 0;
|
|
p.Blue = 0;
|
|
Gop->Blt(Gop, &p, EfiBltVideoFill, 0, 0, 0, 0, 640, 480, 0);
|
|
|
|
// Function Pointers
|
|
*(int *) 0x3000 = (long)&tos_malloc;
|
|
*(int *) 0x3010 = (long)&tos_free;
|
|
*(int *) 0x3020 = (long)&tos_msize;
|
|
*(int *) 0x3030 = (long)&tos_blt;
|
|
*(int *) 0x3040 = (long)&tos_fileread;
|
|
|
|
// Start TempleOS Kernel
|
|
goto *EntryPoint;
|
|
|
|
// Should never get here
|
|
return 0;
|
|
}
|