diff --git a/xtldr/includes/blproto.h b/xtldr/includes/blproto.h index a2b7e59..51cb824 100644 --- a/xtldr/includes/blproto.h +++ b/xtldr/includes/blproto.h @@ -21,6 +21,7 @@ typedef EFI_STATUS (*PBL_ENABLE_PAGING)(IN PLIST_ENTRY MemoryMappings, IN PVOID typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); +typedef EFI_STATUS (*PBL_GET_VIRTUAL_ADDRESS)(IN PLIST_ENTRY MemoryMappings, IN PVOID PhysicalAddress, OUT PVOID *VirtualAddress); typedef EFI_STATUS (*PBL_INIT_VIRTUAL_MEMORY)(IN OUT PLIST_ENTRY MemoryMappings, IN OUT PVOID *MemoryMapAddress); typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN PLIST_ENTRY MemoryMappings, IN UINT_PTR VirtualAddress, IN UINT_PTR PhysicalAddress, IN UINT NumberOfPages, IN BOOLEAN PaeExtension, IN OUT PVOID *PtePointer); typedef VOID (*PBL_GET_STACK)(OUT PVOID *Stack); @@ -39,6 +40,7 @@ typedef struct _XT_BOOT_LOADER_PROTOCOL PBL_FREE_POOL FreePool; PBL_ENABLE_PAGING EnablePaging; PBL_GET_MEMORY_MAP GetMemoryMap; + PBL_GET_VIRTUAL_ADDRESS GetVirtualAddress; PBL_INIT_VIRTUAL_MEMORY InitializeVirtualMemory; PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory; PBL_GET_STACK GetStack; diff --git a/xtldr/includes/xtbl.h b/xtldr/includes/xtbl.h index f03bab9..30e6260 100644 --- a/xtldr/includes/xtbl.h +++ b/xtldr/includes/xtbl.h @@ -114,6 +114,11 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); VOID BlGetStackPointer(OUT PVOID *Stack); +EFI_STATUS +BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, + IN PVOID PhysicalAddress, + OUT PVOID *VirtualAddress); + EFI_STATUS BlGetVolumeDevicePath(IN PUCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, diff --git a/xtldr/memory.c b/xtldr/memory.c index b1360ff..7026718 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.c @@ -366,6 +366,67 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) return STATUS_EFI_SUCCESS; } +/** + * Attempts to find a virtual address of the specified physical address in memory mappings. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param PhysicalAddress + * Supplies a physical address to search for in the mappings. + * + * @param VirtualAddress + * Supplies a buffer, where mapped virtual address of the found mapping will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, + IN PVOID PhysicalAddress, + OUT PVOID *VirtualAddress) +{ + PLOADER_MEMORY_MAPPING Mapping; + PLIST_ENTRY ListEntry; + + /* NULLify virtual address */ + *VirtualAddress = NULL; + + /* Iterate over memory mappings in order to find descriptor containing a physical address */ + ListEntry = MemoryMappings->Flink; + while(ListEntry != MemoryMappings) + { + /* Get mapping from linked list */ + Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + + /* Make sure any virtual address is set */ + if(Mapping->VirtualAddress) + { + /* Check if provided physical address is in range of this mapping */ + if((PhysicalAddress >= Mapping->PhysicalAddress) && + (PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) + { + /* Calculate virtual address based on the mapping */ + *VirtualAddress = PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress; + } + } + + /* Get next element from the list */ + ListEntry = ListEntry->Flink; + } + + /* If virtual address is still NULL, then mapping was not found */ + if(*VirtualAddress == NULL) + { + /* Mapping not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Mapping found, return success */ + return STATUS_EFI_SUCCESS; +} + /** * Initializes virtual memory by adding known and general mappings. * @@ -428,8 +489,8 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, else if(MemoryType != LoaderFree) { /* Add any non-free memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, - (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); + Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); /* Calculate next valid virtual address */ VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index 7469501..7e7a7c2 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -156,27 +156,58 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress { PKERNEL_INITIALIZATION_BLOCK LoaderBlock; EFI_PHYSICAL_ADDRESS Address; + PVOID RuntimeServices; EFI_STATUS Status; UINT BlockPages; + /* Calculate number of pages needed for initialization block */ BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); + /* Allocate memory for kernel initialization block */ Status = XtLdrProtocol->AllocatePages(BlockPages, &Address); if(Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ return Status; } + /* Initialize and zero-fill kernel initialization block */ LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK)); - LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->DbgPrint; + /* Set basic loader block properties */ + LoaderBlock->Size = sizeof(KERNEL_INITIALIZATION_BLOCK); LoaderBlock->Version = INITIALIZATION_BLOCK_VERSION; - XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock, BlockPages, LoaderSystemBlock); + /* No kernel stack available now */ + LoaderBlock->KernelStack = (ULONG_PTR)NULL; + /* Set LoaderInformation block properties */ + LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->DbgPrint; + + /* Attempt to find virtual address of the EFI Runtime Services */ + Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); + if(Status == STATUS_EFI_SUCCESS) + { + /* Set FirmwareInformation block properties */ + LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = RuntimeServices; + } + else + { + /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */ + LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid; + } + + /* Map kernel initialization block */ + XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock, + BlockPages, LoaderSystemBlock); + + /* Calculate next valid virtual address */ *VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); + /* Return success */ return STATUS_EFI_SUCCESS; } diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 9a4c323..85d81fc 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -332,6 +332,7 @@ BlRegisterXtLoaderProtocol() EfiLdrProtocol.FreePool = BlEfiMemoryFreePool; EfiLdrProtocol.EnablePaging = BlEnablePaging; EfiLdrProtocol.GetMemoryMap = BlGetMemoryMap; + EfiLdrProtocol.GetVirtualAddress = BlGetVirtualAddress; EfiLdrProtocol.InitializeVirtualMemory = BlInitializeVirtualMemory; EfiLdrProtocol.MapVirtualMemory = BlMapVirtualMemory; EfiLdrProtocol.GetStack = BlGetStackPointer; diff --git a/xtoskrnl/ke/krnlinit.c b/xtoskrnl/ke/krnlinit.c index fb92900..9812044 100644 --- a/xtoskrnl/ke/krnlinit.c +++ b/xtoskrnl/ke/krnlinit.c @@ -26,6 +26,18 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) /* Print some message to serial console */ DbgPrint(L"Hello world from ExectOS kernel!\n"); + /* Test kernel parameters */ + DbgPrint(L"\n\n------ Kernel parameters block ------\n" + L"Loader block size: %lu\n" + L"Loader block version: %lu\n" + L"EFI Revision: %lu\n" + L"EFI RunTime Revision: %lu\n", + Parameters->Size, + Parameters->Version, + Parameters->FirmwareInformation.EfiFirmware.EfiVersion, + ((PEFI_RUNTIME_SERVICES) Parameters->FirmwareInformation.EfiFirmware.EfiRuntimeServices)->Hdr.Revision + ); + /* Enter infinite kernel thread loop */ for(;;); }