From 1fd9d11f160c10e70311b4176d0fad950b6cfe54 Mon Sep 17 00:00:00 2001 From: Justin Miller Date: Sun, 30 Apr 2023 05:57:10 -0700 Subject: [PATCH] [FREELDR] Add disk access handlers for UEFI (#5219) CORE-11953 --- boot/freeldr/freeldr/arch/uefi/stubs.c | 34 -- boot/freeldr/freeldr/arch/uefi/uefidisk.c | 596 ++++++++++++++++++++++ boot/freeldr/freeldr/uefi.cmake | 7 +- 3 files changed, 600 insertions(+), 37 deletions(-) create mode 100644 boot/freeldr/freeldr/arch/uefi/uefidisk.c diff --git a/boot/freeldr/freeldr/arch/uefi/stubs.c b/boot/freeldr/freeldr/arch/uefi/stubs.c index 75f7ee0fc8b..28f11b7795b 100644 --- a/boot/freeldr/freeldr/arch/uefi/stubs.c +++ b/boot/freeldr/freeldr/arch/uefi/stubs.c @@ -48,40 +48,6 @@ UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, } -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) { diff --git a/boot/freeldr/freeldr/arch/uefi/uefidisk.c b/boot/freeldr/freeldr/arch/uefi/uefidisk.c new file mode 100644 index 00000000000..772cdece7ce --- /dev/null +++ b/boot/freeldr/freeldr/arch/uefi/uefidisk.c @@ -0,0 +1,596 @@ +/* + * PROJECT: FreeLoader UEFI Support + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Disk Access Functions + * COPYRIGHT: Copyright 2022 Justin Miller + */ + +/* INCLUDES ******************************************************************/ + +#include + +#include +DBG_DEFAULT_CHANNEL(WARNING); + +#define TAG_HW_RESOURCE_LIST 'lRwH' +#define TAG_HW_DISK_CONTEXT 'cDwH' +#define FIRST_BIOS_DISK 0x80 +#define FIRST_PARTITION 1 + +typedef struct tagDISKCONTEXT +{ + UCHAR DriveNumber; + ULONG SectorSize; + ULONGLONG SectorOffset; + ULONGLONG SectorCount; + ULONGLONG SectorNumber; +} DISKCONTEXT; + +typedef struct _INTERNAL_UEFI_DISK +{ + UCHAR ArcDriveNumber; + UCHAR NumOfPartitions; + UCHAR UefiRootNumber; + BOOLEAN IsThisTheBootDrive; +} INTERNAL_UEFI_DISK, *PINTERNAL_UEFI_DISK; + +/* GLOBALS *******************************************************************/ + +extern EFI_SYSTEM_TABLE* GlobalSystemTable; +extern EFI_HANDLE GlobalImageHandle; +extern EFI_HANDLE PublicBootHandle; /* Freeldr itself */ + +/* Made to match BIOS */ +PVOID DiskReadBuffer; +UCHAR PcBiosDiskCount; + +UCHAR FrldrBootDrive; +ULONG FrldrBootPartition; +SIZE_T DiskReadBufferSize; +PVOID Buffer; + +static const CHAR Hex[] = "0123456789abcdef"; +static CHAR PcDiskIdentifier[32][20]; + +/* UEFI-specific */ +static ULONG UefiBootRootIdentifier; +static ULONG OffsetToBoot; +static ULONG PublicBootArcDisk; +static INTERNAL_UEFI_DISK* InternalUefiDisk = NULL; +static EFI_GUID bioGuid = BLOCK_IO_PROTOCOL; +static EFI_BLOCK_IO* bio; +static EFI_HANDLE* handles = NULL; + +/* FUNCTIONS *****************************************************************/ + +PCHAR +GetHarddiskIdentifier(UCHAR DriveNumber) +{ + TRACE("GetHarddiskIdentifier: DriveNumber: %d\n", DriveNumber); + return PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK]; +} + +static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors. + +LONG +DiskReportError(BOOLEAN bShowError) +{ + /* Set the reference count */ + if (bShowError) ++lReportError; + else --lReportError; + return lReportError; +} + +static +BOOLEAN +UefiGetBootPartitionEntry( + IN UCHAR DriveNumber, + OUT PPARTITION_TABLE_ENTRY PartitionTableEntry, + OUT PULONG BootPartition) +{ + ULONG PartitionNum; + + TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber - FIRST_BIOS_DISK); + /* UefiBootRoot is the offset into the array of handles where the raw disk of the boot drive is. + * Partitions start with 1 in ARC, but UEFI root drive identitfier is also first partition. */ + PartitionNum = (OffsetToBoot - UefiBootRootIdentifier); + if (PartitionNum == 0) + { + TRACE("Boot PartitionNumber is 0\n"); + /* The OffsetToBoot is equal to the RootIdentifier */ + PartitionNum = 1; + } + + *BootPartition = PartitionNum; + TRACE("UefiGetBootPartitionEntry: Boot Partition is: %d\n", PartitionNum); + return TRUE; +} + +static +ARC_STATUS +UefiDiskClose(ULONG FileId) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT); + return ESUCCESS; +} + +static +ARC_STATUS +UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + RtlZeroMemory(Information, sizeof(*Information)); + + /* + * The ARC specification mentions that for partitions, StartingAddress and + * EndingAddress are the start and end positions of the partition in terms + * of byte offsets from the start of the disk. + * CurrentAddress is the current offset into (i.e. relative to) the partition. + */ + Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize; + Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize; + Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize; + + return ESUCCESS; +} + +static +ARC_STATUS +UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId) +{ + DISKCONTEXT* Context; + UCHAR DriveNumber; + ULONG DrivePartition, SectorSize; + ULONGLONG SectorOffset = 0; + ULONGLONG SectorCount = 0; + ULONG UefiDriveNumber = 0; + PARTITION_TABLE_ENTRY PartitionTableEntry; + + TRACE("UefiDiskOpen: File ID: %d, Path: %s\n", FileId, Path); + + if (DiskReadBufferSize == 0) + { + ERR("DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n"); + ASSERT(FALSE); + return ENOMEM; + } + + if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition)) + return EINVAL; + + TRACE("Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition); + UefiDriveNumber = DriveNumber - FIRST_BIOS_DISK; + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio); + SectorSize = bio->Media->BlockSize; + + if (DrivePartition != 0xff && DrivePartition != 0) + { + if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) + return EINVAL; + + SectorOffset = PartitionTableEntry.SectorCountBeforePartition; + SectorCount = PartitionTableEntry.PartitionSectorCount; + } + else + { + GEOMETRY Geometry; + if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry)) + return EINVAL; + + if (SectorSize != Geometry.BytesPerSector) + { + ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n", + SectorSize, Geometry.BytesPerSector); + } + + SectorOffset = 0; + SectorCount = (ULONGLONG)Geometry.Cylinders * Geometry.Heads * Geometry.Sectors; + } + + Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT); + if (!Context) + return ENOMEM; + + Context->DriveNumber = DriveNumber; + Context->SectorSize = SectorSize; + Context->SectorOffset = SectorOffset; + Context->SectorCount = SectorCount; + Context->SectorNumber = 0; + FsSetDeviceSpecific(*FileId, Context); + return ESUCCESS; +} + +static +ARC_STATUS +UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + UCHAR* Ptr = (UCHAR*)Buffer; + ULONG Length, TotalSectors, MaxSectors, ReadSectors; + ULONGLONG SectorOffset; + BOOLEAN ret; + + ASSERT(DiskReadBufferSize > 0); + + TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize; + MaxSectors = DiskReadBufferSize / Context->SectorSize; + SectorOffset = Context->SectorOffset + Context->SectorNumber; + + // If MaxSectors is 0, this will lead to infinite loop. + // In release builds assertions are disabled, however we also have sanity checks in DiskOpen() + ASSERT(MaxSectors > 0); + + ret = TRUE; + + while (TotalSectors) + { + ReadSectors = min(TotalSectors, MaxSectors); + + ret = MachDiskReadLogicalSectors(Context->DriveNumber, + SectorOffset, + ReadSectors, + DiskReadBuffer); + if (!ret) + break; + + Length = ReadSectors * Context->SectorSize; + Length = min(Length, N); + + RtlCopyMemory(Ptr, DiskReadBuffer, Length); + + Ptr += Length; + N -= Length; + SectorOffset += ReadSectors; + TotalSectors -= ReadSectors; + } + + *Count = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Buffer); + Context->SectorNumber = SectorOffset - Context->SectorOffset; + + return (ret ? ESUCCESS : EIO); +} + +static +ARC_STATUS +UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + LARGE_INTEGER NewPosition = *Position; + + switch (SeekMode) + { + case SeekAbsolute: + break; + case SeekRelative: + NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize); + break; + default: + ASSERT(FALSE); + return EINVAL; + } + + if (NewPosition.QuadPart & (Context->SectorSize - 1)) + return EINVAL; + + /* Convert in number of sectors */ + NewPosition.QuadPart /= Context->SectorSize; + + /* HACK: CDROMs may have a SectorCount of 0 */ + if (Context->SectorCount != 0 && NewPosition.QuadPart >= Context->SectorCount) + return EINVAL; + + Context->SectorNumber = NewPosition.QuadPart; + return ESUCCESS; +} + +static const DEVVTBL UefiDiskVtbl = +{ + UefiDiskClose, + UefiDiskGetFileInformation, + UefiDiskOpen, + UefiDiskRead, + UefiDiskSeek, +}; + +static +VOID +GetHarddiskInformation(UCHAR DriveNumber) +{ + PMASTER_BOOT_RECORD Mbr; + PULONG Buffer; + ULONG i; + ULONG Checksum; + ULONG Signature; + BOOLEAN ValidPartitionTable; + CHAR ArcName[MAX_PATH]; + PARTITION_TABLE_ENTRY PartitionTableEntry; + PCHAR Identifier = PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK]; + + /* Detect disk partition type */ + DiskDetectPartitionType(DriveNumber); + + /* Read the MBR */ + if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer)) + { + ERR("Reading MBR failed\n"); + /* We failed, use a default identifier */ + sprintf(Identifier, "BIOSDISK%d", DriveNumber - FIRST_BIOS_DISK); + return; + } + + Buffer = (ULONG*)DiskReadBuffer; + Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer; + + Signature = Mbr->Signature; + TRACE("Signature: %x\n", Signature); + + /* Calculate the MBR checksum */ + Checksum = 0; + for (i = 0; i < 512 / sizeof(ULONG); i++) + { + Checksum += Buffer[i]; + } + Checksum = ~Checksum + 1; + TRACE("Checksum: %x\n", Checksum); + + ValidPartitionTable = (Mbr->MasterBootRecordMagic == 0xAA55); + + /* Fill out the ARC disk block */ + sprintf(ArcName, "multi(0)disk(0)rdisk(%u)", DriveNumber - FIRST_BIOS_DISK); + AddReactOSArcDiskInfo(ArcName, Signature, Checksum, ValidPartitionTable); + + sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - FIRST_BIOS_DISK); + FsRegisterDevice(ArcName, &UefiDiskVtbl); + + /* Add partitions */ + i = FIRST_PARTITION; + DiskReportError(FALSE); + while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry)) + { + if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED) + { + sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - FIRST_BIOS_DISK, i); + FsRegisterDevice(ArcName, &UefiDiskVtbl); + } + i++; + } + DiskReportError(TRUE); + + InternalUefiDisk[DriveNumber].NumOfPartitions = i; + /* Convert checksum and signature to identifier string */ + Identifier[0] = Hex[(Checksum >> 28) & 0x0F]; + Identifier[1] = Hex[(Checksum >> 24) & 0x0F]; + Identifier[2] = Hex[(Checksum >> 20) & 0x0F]; + Identifier[3] = Hex[(Checksum >> 16) & 0x0F]; + Identifier[4] = Hex[(Checksum >> 12) & 0x0F]; + Identifier[5] = Hex[(Checksum >> 8) & 0x0F]; + Identifier[6] = Hex[(Checksum >> 4) & 0x0F]; + Identifier[7] = Hex[Checksum & 0x0F]; + Identifier[8] = '-'; + Identifier[9] = Hex[(Signature >> 28) & 0x0F]; + Identifier[10] = Hex[(Signature >> 24) & 0x0F]; + Identifier[11] = Hex[(Signature >> 20) & 0x0F]; + Identifier[12] = Hex[(Signature >> 16) & 0x0F]; + Identifier[13] = Hex[(Signature >> 12) & 0x0F]; + Identifier[14] = Hex[(Signature >> 8) & 0x0F]; + Identifier[15] = Hex[(Signature >> 4) & 0x0F]; + Identifier[16] = Hex[Signature & 0x0F]; + Identifier[17] = '-'; + Identifier[18] = (ValidPartitionTable ? 'A' : 'X'); + Identifier[19] = 0; + TRACE("Identifier: %s\n", Identifier); +} + +static +VOID +UefiSetupBlockDevices(VOID) +{ + ULONG BlockDeviceIndex; + ULONG SystemHandleCount; + EFI_STATUS Status; + ULONG i; + + UINTN handle_size = 0; + PcBiosDiskCount = 0; + UefiBootRootIdentifier = 0; + + /* 1) Setup a list of boothandles by using the LocateHandle protocol */ + Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, handles); + handles = MmAllocateMemoryWithType(handle_size, LoaderFirmwareTemporary); + Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, handles); + SystemHandleCount = handle_size / sizeof(EFI_HANDLE); + InternalUefiDisk = MmAllocateMemoryWithType(sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount, LoaderFirmwareTemporary); + + BlockDeviceIndex = 0; + /* 2) Parse the handle list */ + for (i = 0; i < SystemHandleCount; ++i) + { + Status = GlobalSystemTable->BootServices->HandleProtocol(handles[i], &bioGuid, (void**)&bio); + if (handles[i] == PublicBootHandle) + { + OffsetToBoot = i; /* Drive offset in the handles list */ + } + + if (EFI_ERROR(Status) || + bio == NULL || + bio->Media->BlockSize == 0 || + bio->Media->BlockSize > 2048) + { + TRACE("UefiSetupBlockDevices: UEFI has found a block device that failed, skipping\n"); + continue; + } + if (bio->Media->LogicalPartition == FALSE) + { + TRACE("Found root of a HDD\n"); + PcBiosDiskCount++; + InternalUefiDisk[BlockDeviceIndex].ArcDriveNumber = BlockDeviceIndex; + InternalUefiDisk[BlockDeviceIndex].UefiRootNumber = i; + GetHarddiskInformation(BlockDeviceIndex + FIRST_BIOS_DISK); + BlockDeviceIndex++; + } + else if (handles[i] == PublicBootHandle) + { + ULONG increment = 0; + ULONG i; + + /* 3) Grab the offset into the array of handles and decrement per volume (valid partition) */ + for (increment = OffsetToBoot; increment > 0; increment--) + { + GlobalSystemTable->BootServices->HandleProtocol(handles[increment], &bioGuid, (void**)&bio); + if (bio->Media->LogicalPartition == FALSE) + { + TRACE("Found root at increment %u\n", increment); + UefiBootRootIdentifier = increment; + + for (i = 0; i <= PcBiosDiskCount; ++i) + { + /* Now only of the root drive number is equal to this drive we found above */ + if (InternalUefiDisk[i].UefiRootNumber == UefiBootRootIdentifier) + { + InternalUefiDisk[i].IsThisTheBootDrive == TRUE; + PublicBootArcDisk = i; + TRACE("Found Boot drive\n"); + } + } + + break; + } + } + } + } +} + +static +BOOLEAN +UefiSetBootpath(VOID) +{ + TRACE("UefiSetBootpath: Setting up boot path\n"); + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier], &bioGuid, (void**)&bio); + FrldrBootDrive = (FIRST_BIOS_DISK + PublicBootArcDisk); + if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize == 2048) + { + /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM (see isoboot.S) */ + FrldrBootPartition == 0xFF; + RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath), + "multi(0)disk(0)cdrom(%u)", PublicBootArcDisk); + } + else + { + ULONG BootPartition; + PARTITION_TABLE_ENTRY PartitionEntry; + + /* This is a hard disk */ + if (!UefiGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry, &BootPartition)) + { + ERR("Failed to get boot partition entry\n"); + return FALSE; + } + + RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath), + "multi(0)disk(0)rdisk(%u)partition(%lu)", + PublicBootArcDisk, BootPartition); + } + + return TRUE; +} + +BOOLEAN +UefiInitializeBootDevices(VOID) +{ + ULONG i = 0; + + DiskReadBufferSize = EFI_PAGE_SIZE; + DiskReadBuffer = MmAllocateMemoryWithType(DiskReadBufferSize, LoaderFirmwareTemporary); + UefiSetupBlockDevices(); + UefiSetBootpath(); + + /* Add it, if it's a cdrom */ + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier], &bioGuid, (void**)&bio); + if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize == 2048) + { + PMASTER_BOOT_RECORD Mbr; + PULONG Buffer; + ULONG Checksum = 0; + ULONG Signature; + + /* Read the MBR */ + if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer)) + { + ERR("Reading MBR failed\n"); + return FALSE; + } + + Buffer = (ULONG*)DiskReadBuffer; + Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer; + + Signature = Mbr->Signature; + TRACE("Signature: %x\n", Signature); + + /* Calculate the MBR checksum */ + for (i = 0; i < 2048 / sizeof(ULONG); i++) + { + Checksum += Buffer[i]; + } + Checksum = ~Checksum + 1; + TRACE("Checksum: %x\n", Checksum); + + /* Fill out the ARC disk block */ + AddReactOSArcDiskInfo(FrLdrBootPath, Signature, Checksum, TRUE); + + FsRegisterDevice(FrLdrBootPath, &UefiDiskVtbl); + PcBiosDiskCount++; // This is not accounted for in the number of pre-enumerated BIOS drives! + TRACE("Additional boot drive detected: 0x%02X\n", (int)FrldrBootDrive); + } + return TRUE; +} + +UCHAR +UefiGetFloppyCount(VOID) +{ + /* No floppy for you for now... */ + return 0; +} + +BOOLEAN +UefiDiskReadLogicalSectors( + IN UCHAR DriveNumber, + IN ULONGLONG SectorNumber, + IN ULONG SectorCount, + OUT PVOID Buffer) +{ + ULONG UefiDriveNumber; + + UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber; + TRACE("UefiDiskReadLogicalSectors: DriveNumber: %d\n", UefiDriveNumber); + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio); + + /* Devices setup */ + bio->ReadBlocks(bio, bio->Media->MediaId, SectorNumber, SectorCount * bio->Media->BlockSize, Buffer); + return TRUE; +} + +BOOLEAN +UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry) +{ + ULONG UefiDriveNumber; + + UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber; + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio); + Geometry->Cylinders = 1; // Not relevant for the UEFI BIO protocol + Geometry->Heads = 1; // Not relevant for the UEFI BIO protocol + Geometry->Sectors = bio->Media->LastBlock; // Number of sectors per track + Geometry->BytesPerSector = bio->Media->BlockSize; // Number of bytes per sector + + return TRUE; +} + +ULONG +UefiDiskGetCacheableBlockCount(UCHAR DriveNumber) +{ + ULONG UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber; + TRACE("UefiDiskGetCacheableBlockCount: DriveNumber: %d\n", UefiDriveNumber); + + GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio); + return bio->Media->LastBlock; +} diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake index 94b5baa7630..0adb0a25f4b 100644 --- a/boot/freeldr/freeldr/uefi.cmake +++ b/boot/freeldr/freeldr/uefi.cmake @@ -14,11 +14,12 @@ include_directories(BEFORE 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/uefi/uefidisk.c arch/uefi/uefimem.c + arch/uefi/uefisetup.c + arch/uefi/uefiutil.c + arch/uefi/uefivid.c arch/vgafont.c) if(ARCH STREQUAL "i386")