mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[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:
parent
995630ccec
commit
150f721273
15 changed files with 867 additions and 5 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
125
boot/freeldr/freeldr/arch/uefi/stubs.c
Normal file
125
boot/freeldr/freeldr/arch/uefi/stubs.c
Normal 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)
|
||||
{
|
||||
|
||||
}
|
61
boot/freeldr/freeldr/arch/uefi/ueficon.c
Normal file
61
boot/freeldr/freeldr/arch/uefi/ueficon.c
Normal 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++;
|
||||
}
|
||||
}
|
37
boot/freeldr/freeldr/arch/uefi/uefildr.c
Normal file
37
boot/freeldr/freeldr/arch/uefi/uefildr.c
Normal 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)
|
||||
{
|
||||
|
||||
}
|
60
boot/freeldr/freeldr/arch/uefi/uefisetup.c
Normal file
60
boot/freeldr/freeldr/arch/uefi/uefisetup.c
Normal 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");
|
||||
}
|
||||
}
|
38
boot/freeldr/freeldr/arch/uefi/uefiutil.c
Normal file
38
boot/freeldr/freeldr/arch/uefi/uefiutil.c
Normal 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;
|
||||
}
|
||||
|
240
boot/freeldr/freeldr/arch/uefi/uefivid.c
Normal file
240
boot/freeldr/freeldr/arch/uefi/uefivid.c
Normal 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 */
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -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))
|
||||
|
|
122
boot/freeldr/freeldr/include/arch/uefi/machuefi.h
Normal file
122
boot/freeldr/freeldr/include/arch/uefi/machuefi.h
Normal 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);
|
36
boot/freeldr/freeldr/include/arch/uefi/uefildr.h
Normal file
36
boot/freeldr/freeldr/include/arch/uefi/uefildr.h
Normal 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);
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -339,8 +339,10 @@ LoadAndBootDevice(
|
|||
UiUnInitialize("Booting...");
|
||||
IniCleanup();
|
||||
|
||||
#ifndef UEFIBOOT
|
||||
/* Boot the loaded sector code */
|
||||
ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
|
||||
#endif
|
||||
/* Must not return! */
|
||||
return ESUCCESS;
|
||||
}
|
||||
|
|
122
boot/freeldr/freeldr/uefi.cmake
Normal file
122
boot/freeldr/freeldr/uefi.cmake
Normal 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)
|
Loading…
Reference in a new issue