From 7800da4db655e2840c6a8d24d420f1e880708562 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 5 Feb 2017 05:35:44 +0000 Subject: [PATCH] [BOOTLIB]: Implement BlFwGetParameters. [BOOTLIB]: Implement ImgpCopyApplicationBootDevice except for partition devices; [BOOTLIB]: Implement ImgpInitializeBootApplicationParameters. [BOOTLIB]: Fix bug in BlMmGetMemoryMap. [BOOTLIB]: Simplify MmMdCopyList. svn path=/trunk/; revision=73692 --- reactos/boot/environ/include/bl.h | 6 +- .../boot/environ/lib/firmware/efi/firmware.c | 16 ++ reactos/boot/environ/lib/misc/image.c | 157 +++++++++++++++++- reactos/boot/environ/lib/mm/descriptor.c | 60 +++---- reactos/boot/environ/lib/mm/pagealloc.c | 3 + 5 files changed, 204 insertions(+), 38 deletions(-) diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 70649dbd541..169700f1d91 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -184,7 +184,6 @@ C_ASSERT(BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY == 0x240); #define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH 0x10000 #define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME 0x400000 - #define BL_UTL_CHECKSUM_COMPLEMENT 0x10000 #define BL_UTL_CHECKSUM_ROTATE 0x20000 #define BL_UTL_CHECKSUM_NEGATE 0x40000 @@ -1404,6 +1403,11 @@ EfiPrintf ( ... ); +NTSTATUS +BlFwGetParameters( + _In_ PBL_FIRMWARE_DESCRIPTOR Parameters + ); + NTSTATUS BlFwEnumerateDevice ( _In_ PBL_DEVICE_DESCRIPTOR Device diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 04d59d5b78b..a88095d7c1b 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -1784,6 +1784,22 @@ BlpFwInitialize ( return Status; } +NTSTATUS +BlFwGetParameters ( + _In_ PBL_FIRMWARE_DESCRIPTOR Parameters + ) +{ + /* Make sure we got an argument */ + if (!Parameters) + { + return STATUS_INVALID_PARAMETER; + } + + /* Copy the static data */ + *Parameters = *EfiFirmwareParameters; + return STATUS_SUCCESS; +} + NTSTATUS BlFwEnumerateDevice ( _In_ PBL_DEVICE_DESCRIPTOR Device diff --git a/reactos/boot/environ/lib/misc/image.c b/reactos/boot/environ/lib/misc/image.c index be901085ffd..2b4fb8433a7 100644 --- a/reactos/boot/environ/lib/misc/image.c +++ b/reactos/boot/environ/lib/misc/image.c @@ -1604,6 +1604,26 @@ BlpPdParseReturnArguments ( return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +ImgpCopyApplicationBootDevice ( + __in PBL_DEVICE_DESCRIPTOR DestinationDevice, + __in PBL_DEVICE_DESCRIPTOR SourceDevice + ) +{ + /* Is this a partition device? */ + if (SourceDevice->DeviceType != PartitionDevice) + { + /* It's not -- a simple copy will do */ + RtlCopyMemory(DestinationDevice, SourceDevice, SourceDevice->Size); + return STATUS_SUCCESS; + } + + /* TODO */ + EfiPrintf(L"Partition copy not supported\r\n"); + return STATUS_NOT_IMPLEMENTED; + +} + NTSTATUS ImgpInitializeBootApplicationParameters ( _In_ PBL_IMAGE_PARAMETERS ImageParameters, @@ -1616,6 +1636,13 @@ ImgpInitializeBootApplicationParameters ( PIMAGE_NT_HEADERS NtHeaders; BL_IMAGE_PARAMETERS MemoryParameters; LIST_ENTRY MemoryList; + PBL_FIRMWARE_DESCRIPTOR FirmwareParameters; + PBL_DEVICE_DESCRIPTOR BootDevice; + PBL_MEMORY_DATA MemoryData; + PBL_APPLICATION_ENTRY BootAppEntry; + PBL_RETURN_ARGUMENTS ReturnArguments; + PBOOT_APPLICATION_PARAMETER_BLOCK ParameterBlock; + ULONG EntrySize, BufferSize; /* Get the image headers and validate it */ Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders); @@ -1636,10 +1663,138 @@ ImgpInitializeBootApplicationParameters ( 0); if ((Status != STATUS_BUFFER_TOO_SMALL) && (Status != STATUS_SUCCESS)) { + /* We failed due to an unknown reason -- bail out */ return Status; } - EfiPrintf(L"Memory map needs %lx bytes\n", MemoryParameters.BufferSize); + /* Compute the list of the BCD plus the application entry */ + EntrySize = BlGetBootOptionListSize(&AppEntry->BcdData) + + FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData); + + /* Compute the total size required for the entire structure */ + BufferSize = EntrySize + + BlpBootDevice->Size + + MemoryParameters.BufferSize + + sizeof(*ReturnArguments) + + sizeof(*MemoryData) + + sizeof(*FirmwareParameters) + + sizeof(*ParameterBlock); + + /* Check if this gives us enough space */ + if (ImageParameters->BufferSize < BufferSize) + { + /* It does not -- free the existing buffer */ + if (ImageParameters->BufferSize) + { + BlMmFreeHeap(ImageParameters->Buffer); + } + + /* Allocate a new buffer of sufficient size */ + ImageParameters->BufferSize = BufferSize; + ImageParameters->Buffer = BlMmAllocateHeap(BufferSize); + if (!ImageParameters->Buffer) + { + /* Bail out if we couldn't allocate it */ + return STATUS_NO_MEMORY; + } + } + + /* Zero out the parameter block */ + ParameterBlock = (PBOOT_APPLICATION_PARAMETER_BLOCK)ImageParameters->Buffer; + RtlZeroMemory(ParameterBlock, BufferSize); + + /* Initialize it */ + ParameterBlock->Version = BOOT_APPLICATION_VERSION; + ParameterBlock->Size = BufferSize; + ParameterBlock->Signature[0] = BOOT_APPLICATION_SIGNATURE_1; + ParameterBlock->Signature[1] = BOOT_APPLICATION_SIGNATURE_2; + ParameterBlock->MemoryTranslationType = MmTranslationType; + ParameterBlock->ImageType = IMAGE_FILE_MACHINE_I386; + ParameterBlock->ImageBase = (ULONGLONG)ImageBase; + ParameterBlock->ImageSize = NtHeaders->OptionalHeader.SizeOfImage; + + /* Get the offset to the memory data */ + ParameterBlock->MemoryDataOffset = sizeof(*ParameterBlock); + + /* Fill it out */ + MemoryData = (PBL_MEMORY_DATA)((ULONG_PTR)ParameterBlock + + ParameterBlock->MemoryDataOffset); + MemoryData->Version = BL_MEMORY_DATA_VERSION; + MemoryData->MdListOffset = sizeof(*MemoryData); + MemoryData->DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR); + MemoryData->DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage); + + /* And populate the memory map */ + MemoryParameters.Buffer = MemoryData + 1; + Status = BlMmGetMemoryMap(&MemoryList, + &MemoryParameters, + BL_MM_INCLUDE_PERSISTENT_MEMORY | + BL_MM_INCLUDE_MAPPED_ALLOCATED | + BL_MM_INCLUDE_MAPPED_UNALLOCATED | + BL_MM_INCLUDE_UNMAPPED_ALLOCATED | + BL_MM_INCLUDE_RESERVED_ALLOCATED, + 0); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Now that we have the map, indicate the number of descriptors */ + MemoryData->DescriptorCount = MemoryParameters.ActualSize / + MemoryData->DescriptorSize; + + /* Get the offset to the application entry */ + ParameterBlock->AppEntryOffset = ParameterBlock->MemoryDataOffset + + MemoryData->MdListOffset + + MemoryParameters.BufferSize; + + /* Fill it out */ + BootAppEntry = (PBL_APPLICATION_ENTRY)((ULONG_PTR)ParameterBlock + + ParameterBlock->AppEntryOffset); + RtlCopyMemory(BootAppEntry, AppEntry, EntrySize); + + /* Get the offset to the boot device */ + ParameterBlock->BootDeviceOffset = ParameterBlock->AppEntryOffset + + EntrySize; + + /* Fill it out */ + BootDevice = (PBL_DEVICE_DESCRIPTOR)((ULONG_PTR)ParameterBlock + + ParameterBlock->BootDeviceOffset); + Status = ImgpCopyApplicationBootDevice(BootDevice, BlpBootDevice); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Get the offset to the firmware data */ + ParameterBlock->FirmwareParametersOffset = ParameterBlock->BootDeviceOffset + + BootDevice->Size; + + /* Fill it out */ + FirmwareParameters = (PBL_FIRMWARE_DESCRIPTOR)((ULONG_PTR)ParameterBlock + + ParameterBlock-> + FirmwareParametersOffset); + Status = BlFwGetParameters(FirmwareParameters); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Get the offset to the return arguments */ + ParameterBlock->ReturnArgumentsOffset = ParameterBlock->FirmwareParametersOffset + + sizeof(BL_FIRMWARE_DESCRIPTOR); + + /* Fill them out */ + ReturnArguments = (PBL_RETURN_ARGUMENTS)((ULONG_PTR)ParameterBlock + + ParameterBlock-> + ReturnArgumentsOffset); + ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION; + ReturnArguments->DataPage = 0; + ReturnArguments->DataSize = 0; + + /* Structure complete */ + ImageParameters->ActualSize = ParameterBlock->ReturnArgumentsOffset + + sizeof(*ReturnArguments); return STATUS_SUCCESS; } diff --git a/reactos/boot/environ/lib/mm/descriptor.c b/reactos/boot/environ/lib/mm/descriptor.c index 2c7d8595c0f..a6843c4bb0a 100644 --- a/reactos/boot/environ/lib/mm/descriptor.c +++ b/reactos/boot/environ/lib/mm/descriptor.c @@ -290,45 +290,33 @@ MmMdCopyList ( /* Iterate through the list */ First = SourceList->First; NextEntry = First->Flink; - if (First->Flink != First) + while ((NextEntry != First) && (NT_SUCCESS(Status))) { - /* As long as we have success */ - while (NT_SUCCESS(Status)) + /* Make sure there's still space */ + if (Count <= *Used) { - /* Check if there's still space */ - if (Count <= *Used) - { - Status = STATUS_NO_MEMORY; - break; - } - - /* Get the current descriptor */ - Descriptor = CONTAINING_RECORD(NextEntry, - BL_MEMORY_DESCRIPTOR, - ListEntry); - - /* Copy it into one of the descriptors we have */ - RtlCopyMemory(&ListDescriptor[*Used], - Descriptor, - sizeof(*Descriptor)); - - /* Add it to the list we have */ - Status = MmMdAddDescriptorToList(DestinationList, - &ListDescriptor[*Used], - Flags); - ++*Used; - - /* Before moving on, check if we're done */ - Finished = NextEntry->Flink == SourceList->First; - - /* Move to the next entry */ - NextEntry = NextEntry->Flink; - - if (Finished) - { - break; - } + Status = STATUS_NO_MEMORY; + break; } + + /* Get the current descriptor */ + Descriptor = CONTAINING_RECORD(NextEntry, + BL_MEMORY_DESCRIPTOR, + ListEntry); + + /* Copy it into one of the descriptors we have */ + RtlCopyMemory(&ListDescriptor[*Used], + Descriptor, + sizeof(*Descriptor)); + + /* Add it to the list we have */ + Status = MmMdAddDescriptorToList(DestinationList, + &ListDescriptor[*Used], + Flags); + ++*Used; + + /* Move to the next entry */ + NextEntry = NextEntry->Flink; } /* Check if the global descriptors were used */ diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index 886532dfb0e..453caa800af 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -660,6 +660,9 @@ BlMmGetMemoryMap ( return STATUS_INVALID_PARAMETER; } + /* Initialize the memory map list */ + InitializeListHead(MemoryMap); + /* Check which types of memory to dump */ DoFirmware = WhichTypes & BL_MM_INCLUDE_FIRMWARE_MEMORY; DoPersistent = WhichTypes & BL_MM_INCLUDE_PERSISTENT_MEMORY;