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 $ 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 + */ + +#include + +#include + +/* 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 + */ + +#include + +#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 + */ + +#include + +#include + +/* 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 + */ + +#include + +#include +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 + */ + +#include + +#include +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 + */ + +#include + +#include +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 + */ + +#include + +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 + */ + +#pragma once + +/* INCLUDES ******************************************************************/ +#include + +/* UEFI Headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//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 - * Copyright (C) 2008-2009 Hervé Poussineau + * Copyright (C) 2008-2009 HervĂ© Poussineau * * 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 +## + +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 $ + COMMAND ${CMAKE_STRIP} --strip-all $) +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 $) +endif() + +if(RUNTIME_CHECKS) + target_link_libraries(uefildr runtmchk) +endif() + +add_dependencies(uefildr xdk)