[FREELDR] Support compiling freeldr as a UEFI loader + Implement UI functions (#5171)

First batch of changes to implement a UEFI version of freeldr:
- Compile freeldr as EFI binary on top of the existing loader.
- Stub out various functions so we can create a UEFI machine-type in freeldr.
- Implement all of the video output functions so we can display a pretty freeldr BSoD :)
This commit is contained in:
Justin Miller 2023-03-19 12:13:16 -07:00 committed by GitHub
parent 995630ccec
commit 150f721273
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 867 additions and 5 deletions

View file

@ -15,11 +15,9 @@ else()
message(FATAL_ERROR "Unknown ARCH '" ${ARCH} "', cannot generate a valid UEFI boot filename.")
endif()
# FIXME: this command creates a dummy EFI partition, add EFI/BOOT/boot${EFI_PLATFORM_ID}.efi file
# once ReactOS supports UEFI
add_custom_target(efisys
COMMAND native-fatten ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin -format 2880 EFIBOOT -boot ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat.bin -mkdir EFI -mkdir EFI/BOOT
DEPENDS native-fatten fat
COMMAND native-fatten ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin -format 2880 EFIBOOT -boot ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat.bin -mkdir EFI -mkdir EFI/BOOT -add $<TARGET_FILE:uefildr> EFI/BOOT/boot${EFI_PLATFORM_ID}.efi
DEPENDS native-fatten fat uefildr
VERBATIM)
@ -162,4 +160,12 @@ add_custom_target(hybridcd
DEPENDS bootcd livecd
VERBATIM)
# For things like flashing USB drives, we also add the efi file into efi/boot.
add_cd_file(TARGET efisys FILE ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin DESTINATION loader NO_CAB NOT_IN_HYBRIDCD FOR bootcd regtest livecd hybridcd)
add_cd_file(
TARGET uefildr
DESTINATION efi/boot
NO_CAB
NAME_ON_CD boot${EFI_PLATFORM_ID}.efi
FOR livecd hybridcd)

View file

@ -135,3 +135,6 @@ if(ARCH STREQUAL "i386")
endif()
include(pcat.cmake)
if(NOT ARCH STREQUAL "i386" OR NOT (SARCH STREQUAL "pc98" OR SARCH STREQUAL "xbox"))
include(uefi.cmake)
endif()

View file

@ -0,0 +1,125 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI stubs
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#include <debug.h>
/* TODO: Handle this with custom Disk / partition setup */
UCHAR
DriveMapGetBiosDriveNumber(PCSTR DeviceName)
{
return 0;
}
VOID
StallExecutionProcessor(ULONG Microseconds)
{
}
VOID
NTAPI
KeStallExecutionProcessor(ULONG Microseconds)
{
StallExecutionProcessor(Microseconds);
}
VOID
UefiVideoGetFontsFromFirmware(PULONG RomFontPointers)
{
}
VOID
UefiVideoSync(VOID)
{
}
PFREELDR_MEMORY_DESCRIPTOR
UefiMemGetMemoryMap(ULONG *MemoryMapSize)
{
return 0;
}
VOID
UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
PULONG ExtendedBIOSDataSize)
{
}
UCHAR
UefiGetFloppyCount(VOID)
{
return 0;
}
BOOLEAN
UefiDiskReadLogicalSectors(IN UCHAR DriveNumber,
IN ULONGLONG SectorNumber,
IN ULONG SectorCount,
OUT PVOID Buffer)
{
return 0;
}
BOOLEAN
UefiDiskGetDriveGeometry(UCHAR DriveNumber,
PGEOMETRY Geometry)
{
return 0;
}
ULONG
UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
{
return 0;
}
BOOLEAN
UefiInitializeBootDevices(VOID)
{
return 0;
}
PCONFIGURATION_COMPONENT_DATA
UefiHwDetect(VOID)
{
return 0;
}
VOID
UefiPrepareForReactOS(VOID)
{
}
VOID
UefiPcBeep(VOID)
{
/* Not possible on UEFI, for now */
}
BOOLEAN
UefiConsKbHit(VOID)
{
return FALSE;
}
int
UefiConsGetCh(void)
{
return 0;
}
VOID
UefiHwIdle(VOID)
{
}

View file

@ -0,0 +1,61 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI Console output
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#define CHAR_WIDTH 8
#define CHAR_HEIGHT 16
/* GLOBALS ********************************************************************/
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
static unsigned CurrentCursorX = 0;
static unsigned CurrentCursorY = 0;
static unsigned CurrentAttr = 0x0f;
/* FUNCTIONS ******************************************************************/
VOID
UefiConsPutChar(int c)
{
ULONG Width, Height, Unused;
BOOLEAN NeedScroll;
UefiVideoGetDisplaySize(&Width, &Height, &Unused);
NeedScroll = (CurrentCursorY >= Height);
if (NeedScroll)
{
UefiVideoScrollUp();
--CurrentCursorY;
}
if (c == '\r')
{
CurrentCursorX = 0;
}
else if (c == '\n')
{
CurrentCursorX = 0;
if (!NeedScroll)
++CurrentCursorY;
}
else if (c == '\t')
{
CurrentCursorX = (CurrentCursorX + 8) & ~7;
}
else
{
UefiVideoPutChar(c, CurrentAttr, CurrentCursorX, CurrentCursorY);
CurrentCursorX++;
}
if (CurrentCursorX >= Width)
{
CurrentCursorX = 0;
CurrentCursorY++;
}
}

View file

@ -0,0 +1,37 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI Entry point and helpers
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#include <debug.h>
/* GLOBALS ********************************************************************/
EFI_HANDLE GlobalImageHandle;
EFI_SYSTEM_TABLE *GlobalSystemTable;
/* FUNCTIONS ******************************************************************/
EFI_STATUS
EfiEntry(
_In_ EFI_HANDLE ImageHandle,
_In_ EFI_SYSTEM_TABLE *SystemTable)
{
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"UEFI EntryPoint: Starting freeldr from UEFI");
GlobalImageHandle = ImageHandle;
GlobalSystemTable = SystemTable;
BootMain(NULL);
UNREACHABLE;
return 0;
}
VOID __cdecl Reboot(VOID)
{
}

View file

@ -0,0 +1,60 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI Mach Setup
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING);
/* GLOBALS ********************************************************************/
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
extern EFI_HANDLE GlobalImageHandle;
BOOLEAN AcpiPresent = FALSE;
/* FUNCTIONS ******************************************************************/
VOID
MachInit(const char *CmdLine)
{
RtlZeroMemory(&MachVtbl, sizeof(MachVtbl));
MachVtbl.ConsPutChar = UefiConsPutChar;
MachVtbl.ConsKbHit = UefiConsKbHit;
MachVtbl.ConsGetCh = UefiConsGetCh;
MachVtbl.VideoClearScreen = UefiVideoClearScreen;
MachVtbl.VideoSetDisplayMode = UefiVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = UefiVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = UefiVideoGetBufferSize;
MachVtbl.VideoGetFontsFromFirmware = UefiVideoGetFontsFromFirmware;
MachVtbl.VideoSetTextCursorPosition = UefiVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = UefiVideoHideShowTextCursor;
MachVtbl.VideoPutChar = UefiVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = UefiVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = UefiVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = UefiVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = UefiVideoGetPaletteColor;
MachVtbl.VideoSync = UefiVideoSync;
MachVtbl.Beep = UefiPcBeep;
MachVtbl.PrepareForReactOS = UefiPrepareForReactOS;
MachVtbl.GetMemoryMap = UefiMemGetMemoryMap;
MachVtbl.GetExtendedBIOSData = UefiGetExtendedBIOSData;
MachVtbl.GetFloppyCount = UefiGetFloppyCount;
MachVtbl.DiskReadLogicalSectors = UefiDiskReadLogicalSectors;
MachVtbl.DiskGetDriveGeometry = UefiDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = UefiDiskGetCacheableBlockCount;
MachVtbl.GetTime = UefiGetTime;
MachVtbl.InitializeBootDevices = UefiInitializeBootDevices;
MachVtbl.HwDetect = UefiHwDetect;
MachVtbl.HwIdle = UefiHwIdle;
/* Setup GOP */
if (UefiInitalizeVideo() != EFI_SUCCESS)
{
ERR("Failed to setup GOP\n");
}
}

View file

@ -0,0 +1,38 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI Utils source
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING);
/* GLOBALS ********************************************************************/
extern EFI_SYSTEM_TABLE *GlobalSystemTable;
/* FUNCTIONS ******************************************************************/
TIMEINFO*
UefiGetTime(VOID)
{
static TIMEINFO TimeInfo;
EFI_STATUS Status;
EFI_TIME time = {0};
Status = GlobalSystemTable->RuntimeServices->GetTime(&time, NULL);
if (Status != EFI_SUCCESS)
ERR("UefiGetTime: cannot get time status %d\n", Status);
TimeInfo.Year = time.Year;
TimeInfo.Month = time.Month;
TimeInfo.Day = time.Day;
TimeInfo.Hour = time.Hour;
TimeInfo.Minute = time.Minute;
TimeInfo.Second = time.Second;
return &TimeInfo;
}

View file

@ -0,0 +1,240 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI Video output
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <uefildr.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING);
#define CHAR_WIDTH 8
#define CHAR_HEIGHT 16
#define TOP_BOTTOM_LINES 0
#define LOWEST_SUPPORTED_RES 1
/* GLOBALS ********************************************************************/
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
extern EFI_HANDLE GlobalImageHandle;
extern UCHAR BitmapFont8x16[256 * 16];
UCHAR MachDefaultTextColor = COLOR_GRAY;
REACTOS_INTERNAL_BGCONTEXT framebufferData;
EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
/* FUNCTIONS ******************************************************************/
EFI_STATUS
UefiInitalizeVideo(VOID)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL* gop = NULL;
RtlZeroMemory(&framebufferData, sizeof(framebufferData));
Status = GlobalSystemTable->BootServices->LocateProtocol(&EfiGraphicsOutputProtocol, 0, (void**)&gop);
if (Status != EFI_SUCCESS)
{
TRACE("Failed to find GOP with status %d\n", Status);
return Status;
}
/* We don't need high resolutions for freeldr */
gop->SetMode(gop, LOWEST_SUPPORTED_RES);
framebufferData.BaseAddress = (ULONG_PTR)gop->Mode->FrameBufferBase;
framebufferData.BufferSize = gop->Mode->FrameBufferSize;
framebufferData.ScreenWidth = gop->Mode->Info->HorizontalResolution;
framebufferData.ScreenHeight = gop->Mode->Info->VerticalResolution;
framebufferData.PixelsPerScanLine = gop->Mode->Info->PixelsPerScanLine;
framebufferData.PixelFormat = gop->Mode->Info->PixelFormat;
return Status;
}
VOID
UefiPrintFramebufferData(VOID)
{
TRACE("Framebuffer BaseAddress : %X\n", framebufferData.BaseAddress);
TRACE("Framebuffer BufferSize : %X\n", framebufferData.BufferSize);
TRACE("Framebuffer ScreenWidth : %d\n", framebufferData.ScreenWidth);
TRACE("Framebuffer ScreenHeight : %d\n", framebufferData.ScreenHeight);
TRACE("Framebuffer PixelsPerScanLine : %d\n", framebufferData.PixelsPerScanLine);
TRACE("Framebuffer PixelFormat : %d\n", framebufferData.PixelFormat);
}
static ULONG
UefiVideoAttrToSingleColor(UCHAR Attr)
{
UCHAR Intensity;
Intensity = (0 == (Attr & 0x08) ? 127 : 255);
return 0xff000000 |
(0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
(0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
(0 == (Attr & 0x01) ? 0 : Intensity);
}
static VOID
UefiVideoAttrToColors(UCHAR Attr, ULONG *FgColor, ULONG *BgColor)
{
*FgColor = UefiVideoAttrToSingleColor(Attr & 0xf);
*BgColor = UefiVideoAttrToSingleColor((Attr >> 4) & 0xf);
}
static VOID
UefiVideoClearScreenColor(ULONG Color, BOOLEAN FullScreen)
{
ULONG Delta;
ULONG Line, Col;
PULONG p;
Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
for (Line = 0; Line < framebufferData.ScreenHeight - (FullScreen ? 0 : 2 * TOP_BOTTOM_LINES); Line++)
{
p = (PULONG) ((char *) framebufferData.BaseAddress + (Line + (FullScreen ? 0 : TOP_BOTTOM_LINES)) * Delta);
for (Col = 0; Col < framebufferData.ScreenWidth; Col++)
{
*p++ = Color;
}
}
}
VOID
UefiVideoClearScreen(UCHAR Attr)
{
ULONG FgColor, BgColor;
UefiVideoAttrToColors(Attr, &FgColor, &BgColor);
UefiVideoClearScreenColor(BgColor, FALSE);
}
VOID
UefiVideoOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG BgColor)
{
PUCHAR FontPtr;
PULONG Pixel;
UCHAR Mask;
unsigned Line;
unsigned Col;
ULONG Delta;
Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
FontPtr = BitmapFont8x16 + Char * 16;
Pixel = (PULONG) ((char *) framebufferData.BaseAddress +
(Y * CHAR_HEIGHT + TOP_BOTTOM_LINES) * Delta + X * CHAR_WIDTH * 4);
for (Line = 0; Line < CHAR_HEIGHT; Line++)
{
Mask = 0x80;
for (Col = 0; Col < CHAR_WIDTH; Col++)
{
Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
Mask = Mask >> 1;
}
Pixel = (PULONG) ((char *) Pixel + Delta);
}
}
VOID
UefiVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
{
ULONG FgColor = 0;
ULONG BgColor = 0;
if (Ch != 0)
{
UefiVideoAttrToColors(Attr, &FgColor, &BgColor);
UefiVideoOutputChar(Ch, X, Y, FgColor, BgColor);
}
}
VOID
UefiVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
{
*Width = framebufferData.ScreenWidth / CHAR_WIDTH;
*Height = (framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT;
*Depth = 0;
}
VIDEODISPLAYMODE
UefiVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init)
{
/* We only have one mode, semi-text */
return VideoTextMode;
}
ULONG
UefiVideoGetBufferSize(VOID)
{
return ((framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT * (framebufferData.ScreenWidth / CHAR_WIDTH) * 2);
}
VOID
UefiVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
{
PUCHAR OffScreenBuffer = (PUCHAR)Buffer;
ULONG Col, Line;
for (Line = 0; Line < (framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT; Line++)
{
for (Col = 0; Col < framebufferData.ScreenWidth / CHAR_WIDTH; Col++)
{
UefiVideoPutChar(OffScreenBuffer[0], OffScreenBuffer[1], Col, Line);
OffScreenBuffer += 2;
}
}
}
VOID
UefiVideoScrollUp(VOID)
{
ULONG BgColor, Dummy;
ULONG Delta;
Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
ULONG PixelCount = framebufferData.ScreenWidth * CHAR_HEIGHT *
(((framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT) - 1);
PULONG Src = (PULONG)((PUCHAR)framebufferData.BaseAddress + (CHAR_HEIGHT + TOP_BOTTOM_LINES) * Delta);
PULONG Dst = (PULONG)((PUCHAR)framebufferData.BaseAddress + TOP_BOTTOM_LINES * Delta);
UefiVideoAttrToColors(ATTR(COLOR_WHITE, COLOR_BLACK), &Dummy, &BgColor);
while (PixelCount--)
*Dst++ = *Src++;
for (PixelCount = 0; PixelCount < framebufferData.ScreenWidth * CHAR_HEIGHT; PixelCount++)
*Dst++ = BgColor;
}
VOID
UefiVideoSetTextCursorPosition(UCHAR X, UCHAR Y)
{
/* We don't have a cursor yet */
}
VOID
UefiVideoHideShowTextCursor(BOOLEAN Show)
{
/* We don't have a cursor yet */
}
BOOLEAN
UefiVideoIsPaletteFixed(VOID)
{
return 0;
}
VOID
UefiVideoSetPaletteColor(UCHAR Color, UCHAR Red,
UCHAR Green, UCHAR Blue)
{
/* Not supported */
}
VOID
UefiVideoGetPaletteColor(UCHAR Color, UCHAR* Red,
UCHAR* Green, UCHAR* Blue)
{
/* Not supported */
}

View file

@ -55,11 +55,13 @@ static const struct
{"ReactOSSetup", EditCustomBootReactOSSetup, LoadReactOSSetup},
#if defined(_M_IX86) || defined(_M_AMD64)
#ifndef UEFIBOOT
{"Drive" , EditCustomBootDisk , LoadAndBootDevice},
{"Partition" , EditCustomBootPartition , LoadAndBootDevice},
{"BootSector" , EditCustomBootSectorFile, LoadAndBootDevice},
{"Linux" , EditCustomBootLinux, LoadAndBootLinux },
#endif
#endif
#ifdef _M_IX86
{"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows},
#endif
@ -194,8 +196,10 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
ASSERT(*BootType);
#ifdef _M_IX86
#ifndef UEFIBOOT
/* Install the drive mapper according to this section drive mappings */
DriveMapMapDrivesInSection(SectionId);
#endif
#endif
/* Find the suitable OS loader to start */
@ -314,11 +318,13 @@ VOID RunLoader(VOID)
}
#ifdef _M_IX86
#ifndef UEFIBOOT
/* Load additional SCSI driver (if any) */
if (LoadBootDeviceDriver() != ESUCCESS)
{
UiMessageBoxCritical("Unable to load additional boot device drivers.");
}
#endif
#endif
if (!IniFileInitialize())

View file

@ -51,8 +51,10 @@ VOID __cdecl BootMain(IN PCCH CmdLine)
TRACE("BootMain() called.\n");
#ifndef UEFIBOOT
/* Check if the CPU is new enough */
FrLdrCheckCpuCompatibility(); // FIXME: Should be done inside MachInit!
#endif
/* UI pre-initialization */
if (!UiInitialize(FALSE))

View file

@ -0,0 +1,122 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: UEFI "mach" header
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#include <machine.h>
EFI_STATUS
UefiMachInit(_In_ EFI_HANDLE ImageHandle,
_In_ EFI_SYSTEM_TABLE *SystemTable);
VOID
UefiConsPutChar(int Ch);
BOOLEAN
UefiConsKbHit(VOID);
VOID
UefiConsSetCursor(UINT32 Col, UINT32 Row);
int
UefiConsGetCh(void);
EFI_STATUS
UefiInitalizeVideo(VOID);
VOID
UefiVideoClearScreen(UCHAR Attr);
VIDEODISPLAYMODE
UefiVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init);
VOID
UefiVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth);
ULONG
UefiVideoGetBufferSize(VOID);
VOID
UefiVideoGetFontsFromFirmware(PULONG RomFontPointers);
VOID
UefiVideoSetTextCursorPosition(UCHAR X, UCHAR Y);
VOID
UefiVideoHideShowTextCursor(BOOLEAN Show);
VOID
UefiVideoOutputChar(UCHAR Char, unsigned X,
unsigned Y, ULONG FgColor, ULONG BgColor);
VOID
UefiVideoPutChar(int Ch, UCHAR Attr,
unsigned X, unsigned Y);
VOID
UefiVideoCopyOffScreenBufferToVRAM(PVOID Buffer);
BOOLEAN
UefiVideoIsPaletteFixed(VOID);
VOID
UefiVideoSetPaletteColor(UCHAR Color, UCHAR Red,
UCHAR Green, UCHAR Blue);
VOID
UefiVideoGetPaletteColor(UCHAR Color, UCHAR* Red,
UCHAR* Green, UCHAR* Blue);
VOID
UefiVideoSync(VOID);
VOID
UefiPcBeep(VOID);
PFREELDR_MEMORY_DESCRIPTOR
UefiMemGetMemoryMap(ULONG *MemoryMapSize);
VOID
UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
PULONG ExtendedBIOSDataSize);
UCHAR
UefiGetFloppyCount(VOID);
BOOLEAN
UefiDiskReadLogicalSectors(IN UCHAR DriveNumber,
IN ULONGLONG SectorNumber,
IN ULONG SectorCount,
OUT PVOID Buffer);
BOOLEAN
UefiDiskGetDriveGeometry(UCHAR DriveNumber,
PGEOMETRY Geometry);
ULONG
UefiDiskGetCacheableBlockCount(UCHAR DriveNumber);
TIMEINFO*
UefiGetTime(VOID);
BOOLEAN
UefiInitializeBootDevices(VOID);
PCONFIGURATION_COMPONENT_DATA
UefiHwDetect(VOID);
VOID
UefiPrepareForReactOS(VOID);
VOID
UefiHwIdle(VOID);
VOID
UefiInitializeFileSystemSupport(_In_ EFI_HANDLE ImageHandle,
_In_ EFI_SYSTEM_TABLE *SystemTable);
VOID
UefiVideoScrollUp(VOID);

View file

@ -0,0 +1,36 @@
/*
* PROJECT: Freeldr UEFI Extension
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Uefi freeldr core header
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
*/
#pragma once
/* INCLUDES ******************************************************************/
#include <freeldr.h>
/* UEFI Headers */
#include <Uefi.h>
#include <DevicePath.h>
#include <LoadedImage.h>
#include <GraphicsOutput.h>
#include <UgaDraw.h>
#include <BlockIo.h>
#include <Acpi.h>
#include <GlobalVariable.h>
#include <debug.h>
#include <machuefi.h>
//TODO: this version of the struct is temporary
typedef struct _REACTOS_INTERNAL_BGCONTEXT
{
ULONG_PTR BaseAddress;
ULONG BufferSize;
UINT32 ScreenWidth;
UINT32 ScreenHeight;
UINT32 PixelsPerScanLine;
UINT32 PixelFormat;
} REACTOS_INTERNAL_BGCONTEXT, *PREACTOS_INTERNAL_BGCONTEXT;
VOID __cdecl BootMain(IN PCCH CmdLine);

View file

@ -1,7 +1,7 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2008-2009 Hervé Poussineau <hpoussin@reactos.org>
* Copyright (C) 2008-2009 Hervé Poussineau <hpoussin@reactos.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -160,8 +160,10 @@ ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
FileData[DeviceId].FileFuncTable = Ext2Mount(DeviceId);
#endif
#if defined(_M_IX86) || defined(_M_AMD64)
#ifndef UEFIBOOT
if (!FileData[DeviceId].FileFuncTable)
FileData[DeviceId].FileFuncTable = PxeMount(DeviceId);
#endif
#endif
if (!FileData[DeviceId].FileFuncTable)
{

View file

@ -339,8 +339,10 @@ LoadAndBootDevice(
UiUnInitialize("Booting...");
IniCleanup();
#ifndef UEFIBOOT
/* Boot the loaded sector code */
ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
#endif
/* Must not return! */
return ESUCCESS;
}

View file

@ -0,0 +1,122 @@
##
## PROJECT: FreeLoader
## LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
## PURPOSE: Build definitions for UEFI
## COPYRIGHT: Copyright 2023 Justin Miller <justinmiller100@gmail.com>
##
include_directories(BEFORE
${REACTOS_SOURCE_DIR}/boot/environ/include/efi
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include/arch/uefi)
list(APPEND UEFILDR_ARC_SOURCE
${FREELDR_ARC_SOURCE}
arch/uefi/stubs.c
arch/uefi/uefisetup.c
arch/uefi/uefivid.c
arch/uefi/uefiutil.c
arch/uefi/ueficon.c
arch/vgafont.c)
if(ARCH STREQUAL "i386")
list(APPEND UEFILDR_COMMON_ASM_SOURCE
arch/i386/i386trap.S)
elseif(ARCH STREQUAL "amd64")
#TBD
elseif(ARCH STREQUAL "arm")
#TBD
elseif(ARCH STREQUAL "arm64")
#TBD
else()
#TBD
endif()
add_asm_files(uefifreeldr_common_asm ${FREELDR_COMMON_ASM_SOURCE} ${UEFILDR_COMMON_ASM_SOURCE})
add_library(uefifreeldr_common
${uefifreeldr_common_asm}
${UEFILDR_ARC_SOURCE}
${FREELDR_BOOTLIB_SOURCE}
${FREELDR_BOOTMGR_SOURCE}
${FREELDR_NTLDR_SOURCE})
target_compile_definitions(uefifreeldr_common PRIVATE UEFIBOOT)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
# Prevent using SSE (no support in freeldr)
target_compile_options(uefifreeldr_common PUBLIC -mno-sse)
endif()
set(PCH_SOURCE
${UEFILDR_ARC_SOURCE}
${FREELDR_BOOTLIB_SOURCE}
${FREELDR_BOOTMGR_SOURCE}
${FREELDR_NTLDR_SOURCE})
add_pch(uefifreeldr_common include/arch/uefi/uefildr.h PCH_SOURCE)
add_dependencies(uefifreeldr_common bugcodes asm xdk)
## GCC builds need this extra thing for some reason...
if(ARCH STREQUAL "i386" AND NOT MSVC)
target_link_libraries(uefifreeldr_common mini_hal)
endif()
spec2def(uefildr.exe freeldr.spec)
list(APPEND UEFILDR_BASE_SOURCE
include/arch/uefi/uefildr.h
arch/uefi/uefildr.c
${FREELDR_BASE_SOURCE})
if(ARCH STREQUAL "i386")
# Must be included together with disk/scsiport.c
list(APPEND UEFILDR_BASE_SOURCE
${CMAKE_CURRENT_BINARY_DIR}/uefildr.def)
endif()
add_executable(uefildr ${UEFILDR_BASE_SOURCE})
set_target_properties(uefildr PROPERTIES SUFFIX ".efi")
target_compile_definitions(uefildr PRIVATE UEFIBOOT)
if(MSVC)
target_link_options(uefildr PRIVATE /DYNAMICBASE:NO /NXCOMPAT:NO /ignore:4078 /ignore:4254 /DRIVER)
# We don't need hotpatching
remove_target_compile_option(uefildr "/hotpatch")
else()
target_link_options(uefildr PRIVATE -Wl,--exclude-all-symbols,--file-alignment,0x200,--section-alignment,0x200)
# Strip everything, including rossym data
add_custom_command(TARGET uefildr
POST_BUILD
COMMAND ${CMAKE_STRIP} --remove-section=.rossym $<TARGET_FILE:uefildr>
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:uefildr>)
endif()
if(MSVC)
set_subsystem(uefildr EFI_APPLICATION)
else()
set_subsystem(uefildr 10)
endif()
set_entrypoint(uefildr EfiEntry)
if(ARCH STREQUAL "i386")
target_link_libraries(uefildr mini_hal)
endif()
target_link_libraries(uefildr uefifreeldr_common cportlib blcmlib blrtl libcntpr)
# dynamic analysis switches
if(STACK_PROTECTOR)
target_sources(uefildr PRIVATE $<TARGET_OBJECTS:gcc_ssp_nt>)
endif()
if(RUNTIME_CHECKS)
target_link_libraries(uefildr runtmchk)
endif()
add_dependencies(uefildr xdk)