https://git.reactos.org/?p=reactos.git;a=commitdiff;h=150f7212736bfb5da500c…
commit 150f7212736bfb5da500cbafa58c0671d0cc8122
Author: Justin Miller <justinmiller100(a)gmail.com>
AuthorDate: Sun Mar 19 12:13:16 2023 -0700
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Mar 19 20:13:16 2023 +0100
[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
:)
---
boot/boot_images.cmake | 14 +-
boot/freeldr/freeldr/CMakeLists.txt | 3 +
boot/freeldr/freeldr/arch/uefi/stubs.c | 125 +++++++++++
boot/freeldr/freeldr/arch/uefi/ueficon.c | 61 ++++++
boot/freeldr/freeldr/arch/uefi/uefildr.c | 37 ++++
boot/freeldr/freeldr/arch/uefi/uefisetup.c | 60 ++++++
boot/freeldr/freeldr/arch/uefi/uefiutil.c | 38 ++++
boot/freeldr/freeldr/arch/uefi/uefivid.c | 240 ++++++++++++++++++++++
boot/freeldr/freeldr/bootmgr.c | 6 +
boot/freeldr/freeldr/freeldr.c | 2 +
boot/freeldr/freeldr/include/arch/uefi/machuefi.h | 122 +++++++++++
boot/freeldr/freeldr/include/arch/uefi/uefildr.h | 36 ++++
boot/freeldr/freeldr/lib/fs/fs.c | 4 +-
boot/freeldr/freeldr/miscboot.c | 2 +
boot/freeldr/freeldr/uefi.cmake | 122 +++++++++++
15 files changed, 867 insertions(+), 5 deletions(-)
diff --git a/boot/boot_images.cmake b/boot/boot_images.cmake
index c0c9a957672..6ceb37fee73 100644
--- a/boot/boot_images.cmake
+++ b/boot/boot_images.cmake
@@ -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)
diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt
index 740a0a5192c..22b58246ea8 100644
--- a/boot/freeldr/freeldr/CMakeLists.txt
+++ b/boot/freeldr/freeldr/CMakeLists.txt
@@ -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()
diff --git a/boot/freeldr/freeldr/arch/uefi/stubs.c
b/boot/freeldr/freeldr/arch/uefi/stubs.c
new file mode 100644
index 00000000000..b3d574fb00f
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/stubs.c
@@ -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(a)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)
+{
+
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/ueficon.c
b/boot/freeldr/freeldr/arch/uefi/ueficon.c
new file mode 100644
index 00000000000..78c67d9c6e8
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/ueficon.c
@@ -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(a)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++;
+ }
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefildr.c
b/boot/freeldr/freeldr/arch/uefi/uefildr.c
new file mode 100644
index 00000000000..e06ff9a1c5b
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefildr.c
@@ -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(a)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)
+{
+
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefisetup.c
b/boot/freeldr/freeldr/arch/uefi/uefisetup.c
new file mode 100644
index 00000000000..bd223da465f
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefisetup.c
@@ -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(a)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");
+ }
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefiutil.c
b/boot/freeldr/freeldr/arch/uefi/uefiutil.c
new file mode 100644
index 00000000000..9dafea22b6c
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefiutil.c
@@ -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(a)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;
+}
+
diff --git a/boot/freeldr/freeldr/arch/uefi/uefivid.c
b/boot/freeldr/freeldr/arch/uefi/uefivid.c
new file mode 100644
index 00000000000..5bd869fcfd4
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefivid.c
@@ -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(a)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 */
+}
diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c
index c866502a6aa..2c837951fec 100644
--- a/boot/freeldr/freeldr/bootmgr.c
+++ b/boot/freeldr/freeldr/bootmgr.c
@@ -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())
diff --git a/boot/freeldr/freeldr/freeldr.c b/boot/freeldr/freeldr/freeldr.c
index 16af2375097..da9f8964fdb 100644
--- a/boot/freeldr/freeldr/freeldr.c
+++ b/boot/freeldr/freeldr/freeldr.c
@@ -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))
diff --git a/boot/freeldr/freeldr/include/arch/uefi/machuefi.h
b/boot/freeldr/freeldr/include/arch/uefi/machuefi.h
new file mode 100644
index 00000000000..ba878e30972
--- /dev/null
+++ b/boot/freeldr/freeldr/include/arch/uefi/machuefi.h
@@ -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(a)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);
diff --git a/boot/freeldr/freeldr/include/arch/uefi/uefildr.h
b/boot/freeldr/freeldr/include/arch/uefi/uefildr.h
new file mode 100644
index 00000000000..8074a615289
--- /dev/null
+++ b/boot/freeldr/freeldr/include/arch/uefi/uefildr.h
@@ -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(a)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);
diff --git a/boot/freeldr/freeldr/lib/fs/fs.c b/boot/freeldr/freeldr/lib/fs/fs.c
index 92cb3ef0362..3326b1951d6 100644
--- a/boot/freeldr/freeldr/lib/fs/fs.c
+++ b/boot/freeldr/freeldr/lib/fs/fs.c
@@ -1,7 +1,7 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp(a)sginet.com>
- * Copyright (C) 2008-2009 Herv� Poussineau <hpoussin(a)reactos.org>
+ * Copyright (C) 2008-2009 Hervé Poussineau <hpoussin(a)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)
{
diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c
index 6aca738b773..445cecc9e3f 100644
--- a/boot/freeldr/freeldr/miscboot.c
+++ b/boot/freeldr/freeldr/miscboot.c
@@ -339,8 +339,10 @@ LoadAndBootDevice(
UiUnInitialize("Booting...");
IniCleanup();
+#ifndef UEFIBOOT
/* Boot the loaded sector code */
ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
+#endif
/* Must not return! */
return ESUCCESS;
}
diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake
new file mode 100644
index 00000000000..21710408dfc
--- /dev/null
+++ b/boot/freeldr/freeldr/uefi.cmake
@@ -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(a)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)