ReactOS 0.4.15-dev-7788-g1ad9096
zeropage.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for zeropage.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MiFreeInitializationCode (IN PVOID StartVa, IN PVOID EndVa)
 
VOID NTAPI MmZeroPageThread (VOID)
 

Variables

KEVENT MmZeroingPageEvent
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file zeropage.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file zeropage.c.

Function Documentation

◆ MiFindInitializationCode()

VOID NTAPI MiFindInitializationCode ( OUT PVOID StartVa,
OUT PVOID EndVa 
)

Definition at line 1487 of file sysldr.c.

1489{
1490 ULONG Size, SectionCount, Alignment;
1491 PLDR_DATA_TABLE_ENTRY LdrEntry;
1492 ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1493 PLIST_ENTRY NextEntry;
1494 PIMAGE_NT_HEADERS NtHeader;
1495 PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1496 BOOLEAN InitFound;
1498
1499 /* So we don't free our own code yet */
1501
1502 /* Assume failure */
1503 *StartVa = NULL;
1504
1505 /* Acquire the necessary locks while we loop the list */
1509 KernelMode,
1510 FALSE,
1511 NULL);
1513
1514 /* Loop all loaded modules */
1515 NextEntry = PsLoadedModuleList.Flink;
1516 while (NextEntry != &PsLoadedModuleList)
1517 {
1518 /* Get the loader entry and its DLL base */
1519 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1520 DllBase = (ULONG_PTR)LdrEntry->DllBase;
1521
1522 /* Only process boot loaded images. Other drivers are processed by
1523 MmFreeDriverInitialization */
1524 if (LdrEntry->Flags & LDRP_MM_LOADED)
1525 {
1526 /* Keep going */
1527 NextEntry = NextEntry->Flink;
1528 continue;
1529 }
1530
1531 /* Get the NT header */
1532 NtHeader = RtlImageNtHeader((PVOID)DllBase);
1533 if (!NtHeader)
1534 {
1535 /* Keep going */
1536 NextEntry = NextEntry->Flink;
1537 continue;
1538 }
1539
1540 /* Get the first section, the section count, and scan them all */
1541 Section = IMAGE_FIRST_SECTION(NtHeader);
1542 SectionCount = NtHeader->FileHeader.NumberOfSections;
1543 InitStart = 0;
1544 while (SectionCount > 0)
1545 {
1546 /* Assume failure */
1547 InitFound = FALSE;
1548
1549 /* Is this the INIT section or a discardable section? */
1550 if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1552 {
1553 /* Remember this */
1554 InitFound = TRUE;
1555 InitSection = Section;
1556 }
1557
1558 if (InitFound)
1559 {
1560 /* Pick the biggest size -- either raw or virtual */
1561 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1562
1563 /* Read the section alignment */
1565
1566 /* Get the start and end addresses */
1567 InitStart = DllBase + Section->VirtualAddress;
1568 InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1569
1570 /* Align the addresses to PAGE_SIZE */
1571 InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1572 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1573
1574 /* Have we reached the last section? */
1575 if (SectionCount == 1)
1576 {
1577 /* Remember this */
1578 LastSection = Section;
1579 }
1580 else
1581 {
1582 /* We have not, loop all the sections */
1583 LastSection = NULL;
1584 do
1585 {
1586 /* Keep going until we find a non-discardable section range */
1587 SectionCount--;
1588 Section++;
1590 {
1591 /* Discardable, so record it, then keep going */
1592 LastSection = Section;
1593 }
1594 else
1595 {
1596 /* Non-contigous discard flag, or no flag, break out */
1597 break;
1598 }
1599 }
1600 while (SectionCount > 1);
1601 }
1602
1603 /* Have we found a discardable or init section? */
1604 if (LastSection)
1605 {
1606 /* Pick the biggest size -- either raw or virtual */
1607 Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1608
1609 /* Use this as the end of the section address */
1610 InitEnd = DllBase + LastSection->VirtualAddress + Size;
1611
1612 /* Have we reached the last section yet? */
1613 if (SectionCount != 1)
1614 {
1615 /* Then align this accross the session boundary */
1616 InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1617 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1618 }
1619 }
1620
1621 /* Make sure we don't let the init section go past the image */
1622 ImageEnd = DllBase + LdrEntry->SizeOfImage;
1623 if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1624
1625 /* Make sure we have a valid, non-zero init section */
1626 if (InitStart < InitEnd)
1627 {
1628 /* Make sure we are not within this code itself */
1629 if ((InitCode >= InitStart) && (InitCode < InitEnd))
1630 {
1631 /* Return it, we can't free ourselves now */
1632 ASSERT(*StartVa == 0);
1633 *StartVa = (PVOID)InitStart;
1634 *EndVa = (PVOID)InitEnd;
1635 }
1636 else
1637 {
1638 /* This isn't us -- go ahead and free it */
1639 ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1640 DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1641 (PVOID)InitStart,
1642 (PVOID)InitEnd,
1643 &LdrEntry->BaseDllName,
1644 LdrEntry->DllBase,
1645 InitSection->Name);
1646 MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1647 }
1648 }
1649 }
1650
1651 /* Move to the next section */
1652 SectionCount--;
1653 Section++;
1654 }
1655
1656 /* Move to the next module */
1657 NextEntry = NextEntry->Flink;
1658 }
1659
1660 /* Release the locks and return */
1664}
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlImageNtHeader
Definition: compat.h:806
#define ULONG_PTR
Definition: config.h:101
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
union Alignment_ Alignment
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
if(dx< 0)
Definition: linetemp.h:194
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define DPRINT
Definition: sndvol32.h:71
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_SECTION_HEADER::@1555 Misc
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define max(a, b)
Definition: svc.c:63
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1487
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1464
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
@ WrVirtualMemory
Definition: ketypes.h:433

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

VOID NTAPI MiFreeInitializationCode ( IN PVOID  StartVa,
IN PVOID  EndVa 
)

Definition at line 1464 of file sysldr.c.

1466{
1467 PMMPTE PointerPte;
1468 PFN_NUMBER PagesFreed;
1469
1470 /* Get the start PTE */
1471 PointerPte = MiAddressToPte(InitStart);
1472 ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1473
1474 /* Compute the number of pages we expect to free */
1475 PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1476
1477 /* Try to actually free them */
1478 PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1479 PagesFreed,
1480 0,
1481 NULL);
1482}
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MmZeroPageThread()

VOID NTAPI MmZeroPageThread ( VOID  )

Definition at line 36 of file zeropage.c.

37{
39 PVOID StartAddress, EndAddress;
40 PVOID WaitObjects[2];
41
42 /* Get the discardable sections to free them */
43 MiFindInitializationCode(&StartAddress, &EndAddress);
44 if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
45 DPRINT("Free pages: %lx\n", MmAvailablePages);
46
47 /* Set our priority to 0 */
48 Thread->BasePriority = 0;
50
51 /* Setup the wait objects */
52 WaitObjects[0] = &MmZeroingPageEvent;
53// WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
54
55 while (TRUE)
56 {
58
60 WaitObjects,
61 WaitAny,
64 FALSE,
65 NULL,
66 NULL);
67 OldIrql = MiAcquirePfnLock();
68
69 while (TRUE)
70 {
71 ULONG PageCount = 0;
72 PMMPFN Pfn1 = (PMMPFN)LIST_HEAD;
73 PVOID ZeroAddress;
74 PFN_NUMBER PageIndex, FreePage;
75
76 while (PageCount < MI_ZERO_PTES)
77 {
78 PMMPFN Pfn2;
79
81 break;
82
83 PageIndex = MmFreePageListHead.Flink;
84 ASSERT(PageIndex != LIST_HEAD);
86 MI_SET_PROCESS2("Kernel 0 Loop");
88
89 /* The first global free page should also be the first on its own list */
90 if (FreePage != PageIndex)
91 {
92 KeBugCheckEx(PFN_LIST_CORRUPT,
93 0x8F,
95 PageIndex,
96 0);
97 }
98
99 Pfn2 = MiGetPfnEntry(PageIndex);
100 Pfn2->u1.Flink = (PFN_NUMBER)Pfn1;
101 Pfn1 = Pfn2;
102 PageCount++;
103 }
104 MiReleasePfnLock(OldIrql);
105
106 if (PageCount == 0)
107 {
109 break;
110 }
111
112 ZeroAddress = MiMapPagesInZeroSpace(Pfn1, PageCount);
113 ASSERT(ZeroAddress);
114 KeZeroPages(ZeroAddress, PageCount * PAGE_SIZE);
115 MiUnmapPagesInZeroSpace(ZeroAddress, PageCount);
116
117 OldIrql = MiAcquirePfnLock();
118
119 while (Pfn1 != (PMMPFN)LIST_HEAD)
120 {
121 PageIndex = MiGetPfnEntryIndex(Pfn1);
122 Pfn1 = (PMMPFN)Pfn1->u1.Flink;
124 }
125 }
126 }
127}
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KeGetCurrentThread
Definition: hal.h:55
#define MI_GET_PAGE_COLOR(x)
Definition: miarm.h:231
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:779
@ WaitAny
#define MI_ZERO_PTES
Definition: mm.h:82
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: cpu.c:56
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
@ MI_USAGE_ZERO_LOOP
Definition: mm.h:341
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1067
struct _MMPFN * PMMPFN
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
VOID NTAPI MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:187
PVOID NTAPI MiMapPagesInZeroSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:111
#define MI_SET_USAGE(x)
Definition: mm.h:317
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
PFN_NUMBER Total
Definition: mm.h:443
PFN_NUMBER Flink
Definition: mm.h:445
Definition: mm.h:374
PFN_NUMBER Flink
Definition: mm.h:377
union _MMPFN::@1788 u1
#define LIST_HEAD(name, type)
Definition: queue.h:167
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ WrFreePage
Definition: ketypes.h:423
@ FreePage
Definition: ketypes.h:416
VOID NTAPI MiFreeInitializationCode(IN PVOID StartVa, IN PVOID EndVa)
Definition: sysldr.c:1464
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1487
KEVENT MmZeroingPageEvent
Definition: zeropage.c:20

Referenced by Phase1Initialization().

Variable Documentation

◆ MmZeroingPageEvent

KEVENT MmZeroingPageEvent

Definition at line 20 of file zeropage.c.

Referenced by MiInsertPageInFreeList(), MmArmInitSystem(), and MmZeroPageThread().