diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 321a694f0d0..582af62037d 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -4420,63 +4420,6 @@ NtExtendSection(IN HANDLE SectionHandle, return STATUS_NOT_IMPLEMENTED; } - -/********************************************************************** - * NAME INTERNAL - * MmAllocateSection@4 - * - * DESCRIPTION - * - * ARGUMENTS - * Length - * - * RETURN VALUE - * - * NOTE - * Code taken from ntoskrnl/mm/special.c. - * - * REVISIONS - */ -PVOID NTAPI -MmAllocateSection (IN ULONG Length, PVOID BaseAddress) -{ - PVOID Result; - MEMORY_AREA* marea; - NTSTATUS Status; - PMMSUPPORT AddressSpace; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - - DPRINT("MmAllocateSection(Length %x)\n",Length); - - BoundaryAddressMultiple.QuadPart = 0; - - AddressSpace = MmGetKernelAddressSpace(); - Result = BaseAddress; - MmLockAddressSpace(AddressSpace); - Status = MmCreateMemoryArea (AddressSpace, - MEMORY_AREA_SYSTEM, - &Result, - Length, - 0, - &marea, - FALSE, - 0, - BoundaryAddressMultiple); - MmUnlockAddressSpace(AddressSpace); - - if (!NT_SUCCESS(Status)) - { - return (NULL); - } - DPRINT("Result %p\n",Result); - - /* Create a virtual mapping for this memory area */ - MmMapMemoryArea(Result, Length, MC_NPPOOL, PAGE_READWRITE); - - return ((PVOID)Result); -} - - /********************************************************************** * NAME EXPORTED * MmMapViewOfSection diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index 3c6946d6b1b..281a3966bb2 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -4,14 +4,19 @@ * FILE: ntoskrnl/mm/sysldr.c * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files. * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +* ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include #define NDEBUG #include +#line 16 "ARMĀ³::LOADER" +#define MODULE_INVOLVED_IN_ARM3 +#include "./ARM3/miarm.h" + /* GCC's incompetence strikes again */ __inline VOID @@ -25,7 +30,7 @@ sprintf_nt(IN PCHAR Buffer, va_end(ap); } -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ LIST_ENTRY PsLoadedModuleList; LIST_ENTRY MmLoadedUserImageList; @@ -39,7 +44,7 @@ PVOID MmLastUnloadedDrivers; PVOID MmTriageActionTaken; PVOID KernelVerifier; -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/ PVOID NTAPI @@ -68,25 +73,6 @@ MiCacheImageSymbols(IN PVOID BaseAddress) return DebugDirectory; } -VOID -NTAPI -MiFreeBootDriverMemory(PVOID BaseAddress, - ULONG Length) -{ - ULONG i; - - /* Loop each page */ - for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) - { - /* Free the page */ - MmDeleteVirtualMapping(NULL, - (PVOID)((ULONG_PTR)BaseAddress + i * PAGE_SIZE), - TRUE, - NULL, - NULL); - } -} - NTSTATUS NTAPI MiLoadImageSection(IN OUT PVOID *SectionPtr, @@ -103,8 +89,10 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, KAPC_STATE ApcState; LARGE_INTEGER SectionOffset = {{0, 0}}; BOOLEAN LoadSymbols = FALSE; - ULONG DriverSize; + PFN_NUMBER PteCount; + PMMPTE PointerPte, LastPte; PVOID DriverBase; + MMPTE TempPte; PAGED_CODE(); /* Detect session load */ @@ -117,7 +105,7 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, /* Not session load, shouldn't have an entry */ ASSERT(LdrEntry == NULL); - + /* Attach to the system process */ KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); @@ -159,16 +147,37 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, KeUnstackDetachProcess(&ApcState); return Status; } + + /* Reserve system PTEs needed */ + PteCount = ROUND_TO_PAGES(Section->ImageSection->ImageSize) >> PAGE_SHIFT; + PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace); + if (!PointerPte) return STATUS_INSUFFICIENT_RESOURCES; + + /* New driver base */ + LastPte = PointerPte + PteCount; + DriverBase = MiPteToAddress(PointerPte); - /* Get the driver size */ - DriverSize = Section->ImageSection->ImageSize; - - /* Allocate a virtual section for the module */ - DriverBase = MmAllocateSection(DriverSize, NULL); + /* The driver is here */ *ImageBase = DriverBase; + /* Loop the new driver PTEs */ + TempPte = ValidKernelPte; + while (PointerPte < LastPte) + { + /* Allocate a page */ + TempPte.u.Hard.PageFrameNumber = MmAllocPage(MC_NPPOOL); + + /* Write it */ + ASSERT(PointerPte->u.Hard.Valid == 0); + ASSERT(TempPte.u.Hard.Valid == 1); + *PointerPte = TempPte; + + /* Move on */ + PointerPte++; + } + /* Copy the image */ - RtlCopyMemory(DriverBase, Base, DriverSize); + RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT); /* Now unmap the view */ Status = MmUnmapViewOfSection(Process, Base); @@ -1210,6 +1219,10 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PIMAGE_DATA_DIRECTORY DataDirectory; PVOID DllBase, NewImageAddress; NTSTATUS Status; + PMMPTE PointerPte, StartPte, LastPte; + PFN_NUMBER PteCount; + PMMPFN Pfn1; + MMPTE TempPte, OldPte; /* Loop driver list */ for (NextEntry = LoaderBlock->LoadOrderListHead.Flink; @@ -1266,30 +1279,71 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Remember the original address */ DllBase = LdrEntry->DllBase; - - /* Allocate a virtual section for the module */ - NewImageAddress = MmAllocateSection(LdrEntry->SizeOfImage, NULL); - if (!NewImageAddress) + + /* Get the first PTE and the number of PTEs we'll need */ + PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase); + PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT; + LastPte = StartPte + PteCount; + + /* Loop the PTEs */ + while (PointerPte < LastPte) + { + /* Mark the page modified in the PFN database */ + ASSERT(PointerPte->u.Hard.Valid == 1); + Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte)); + ASSERT(Pfn1->u3.e1.Rom == 0); + Pfn1->u3.e1.Modified = TRUE; + + /* Next */ + PointerPte++; + } + + /* Now reserve system PTEs for the image */ + PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace); + if (!PointerPte) { /* Shouldn't happen */ DPRINT1("[Mm0]: Couldn't allocate driver section!\n"); while (TRUE); } + + /* This is the new virtual address for the module */ + LastPte = PointerPte + PteCount; + NewImageAddress = MiPteToAddress(PointerPte); /* Sanity check */ DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress); ASSERT(ExpInitializationPhase == 0); - - /* Now copy the entire driver over */ - RtlCopyMemory(NewImageAddress, DllBase, LdrEntry->SizeOfImage); + + /* Loop the new driver PTEs */ + TempPte = ValidKernelPte; + while (PointerPte < LastPte) + { + /* Copy the old data */ + OldPte = *StartPte; + ASSERT(OldPte.u.Hard.Valid == 1); + + /* Set page number from the loader's memory */ + TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber; + + /* Write it */ + ASSERT(PointerPte->u.Hard.Valid == 0); + ASSERT(TempPte.u.Hard.Valid == 1); + *PointerPte = TempPte; + + /* Move on */ + PointerPte++; + StartPte++; + } + + /* Update position */ + PointerPte -= PteCount; /* Sanity check */ ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase); /* Set the image base to the address where the loader put it */ NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase; - NtHeader = RtlImageNtHeader(NewImageAddress); - NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase; /* Check if we had relocations */ if (ValidRelocs) @@ -1323,10 +1377,9 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) LdrEntry->Flags |= LDRP_SYSTEM_MAPPED; LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress + NtHeader->OptionalHeader.AddressOfEntryPoint); - LdrEntry->SizeOfImage = LdrEntry->SizeOfImage; - - /* Free the old copy */ - MiFreeBootDriverMemory(DllBase, LdrEntry->SizeOfImage); + LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT; + + /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */ } }