00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "mi.h"
00024
00025
#ifdef ALLOC_PRAGMA
00026
#pragma alloc_text(INIT,MiInitMachineDependent)
00027
#endif
00028
00029
extern VOID
00030
KeInitializeVhpt (
00031 IN PVOID Virtual,
00032 IN ULONG Size
00033 );
00034
00035
extern VOID
00036
KeFillLargePdePinned (
00037 IN
PMMPTE Pte,
00038 IN PVOID Virtual
00039 );
00040
00041
VOID
00042
MiConvertToSuperPages(
00043 PVOID StartVirtual,
00044 PVOID EndVirtual,
00045 SIZE_T PageSize,
00046 ULONG PageShift
00047 );
00048
00049
VOID
00050
MiConvertBackToStandardPages(
00051 IN PVOID StartVirtual,
00052 IN PVOID EndVirtual
00053 );
00054
00055
VOID
00056
MiBuildPageTableForDrivers(
00057 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00058 );
00059
00060
VOID
00061
MiBuildPageTableForLoaderMemory(
00062 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00063 );
00064
00065
VOID
00066
MiRemoveLoaderSuperPages(
00067 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00068 );
00069
00070
VOID
00071
MiMakeKernelPagesPermanent(
00072 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00073 );
00074
00075
VOID
00076
MiCheckMemoryDescriptorList(
00077 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00078 );
00079
00080 ULONG_PTR
MmKseg3VhptBase;
00081 ULONG
MmKseg3VhptPs;
00082
00083 PFN_NUMBER
MmSystemParentTablePage;
00084 MMPTE MiSystemSelfMappedPte;
00085 MMPTE MiUserSelfMappedPte;
00086 PVOID
MiKseg0Start = 0;
00087 PVOID
MiKseg0End = 0;
00088 BOOLEAN
MiKseg0Mapping =
TRUE;
00089 BOOLEAN
MiPrintMemoryDescriptors =
FALSE;
00090 PFN_NUMBER
MiNtoskrnlPhysicalBase;
00091 ULONG_PTR
MiNtoskrnlVirtualBase;
00092 ULONG
MiNtoskrnlPageShift;
00093 PFN_NUMBER
MiWasteStart = 0;
00094 PFN_NUMBER
MiWasteEnd = 0;
00095
00096 #define MiGetKSegPteAddress(Va) ((PMMPTE)__thash((ULONG_PTR)(Va)))
00097
00098 #define _x1mb (1024*1024)
00099 #define _x1mbnp ((1024*1024) >> PAGE_SHIFT)
00100 #define _x4mb (1024*1024*4)
00101 #define _x4mbnp ((1024*1024*4) >> PAGE_SHIFT)
00102 #define _x16mb (1024*1024*16)
00103 #define _x16mbnp ((1024*1024*16) >> PAGE_SHIFT)
00104 #define _x32mb (1024*1024*32)
00105 #define _x32mbnp ((1024*1024*32) >> PAGE_SHIFT)
00106 #define _x64mb (1024*1024*64)
00107 #define _x64mbnp ((1024*1024*64) >> PAGE_SHIFT)
00108 #define _x256mb (1024*1024*256)
00109 #define _x256mbnp ((1024*1024*256) >> PAGE_SHIFT)
00110 #define _x512mb (1024*1024*512)
00111 #define _x512mbnp ((1024*1024*512) >> PAGE_SHIFT)
00112 #define _x4gb (0x100000000UI64)
00113 #define _x4gbnp (0x100000000UI64 >> PAGE_SHIFT)
00114
00115 #define ADD_HIGH_MEMORY 0
00116
00117
#if ADD_HIGH_MEMORY
00118
MEMORY_ALLOCATION_DESCRIPTOR MiHighMemoryDescriptor;
00119
#endif
00120
00121 PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
00122 PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLargest =
NULL;
00123 PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLowMem =
NULL;
00124 PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorNonPaged =
NULL;
00125
00126 PFN_NUMBER
MiNextPhysicalPage;
00127 PFN_NUMBER
MiNumberOfPages;
00128 PFN_NUMBER
MiOldFreeDescriptorBase;
00129 PFN_NUMBER
MiOldFreeDescriptorCount;
00130
00131
00132
00133
00134
00135 ULONG
MiImplVirtualMsb = 50;
00136
00137
00138 PFN_NUMBER
00139 MiGetNextPhysicalPage (
00140 VOID
00141 )
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 {
00167
00168
00169
00170
00171
00172
00173
00174
if (
MiNumberOfPages != 0) {
00175
MiNumberOfPages -= 1;
00176
return MiNextPhysicalPage++;
00177
00178 }
else {
00179
00180
00181
00182
00183
00184
00185
if (
MiFreeDescriptor ==
MiFreeDescriptorLargest) {
00186
00187
KeBugCheckEx(INSTALL_MORE_MEMORY,
00188
MmNumberOfPhysicalPages,
00189
MmLowestPhysicalPage,
00190
MmHighestPhysicalPage,
00191 0);
00192
00193
return 0;
00194
00195 }
else if (
MiFreeDescriptor ==
MiFreeDescriptorLowMem) {
00196
00197
MiOldFreeDescriptorCount =
MiFreeDescriptorLargest->
PageCount;
00198
MiOldFreeDescriptorBase =
MiFreeDescriptorLargest->
BasePage;
00199
00200
MiFreeDescriptor =
MiFreeDescriptorLargest;
00201
MiNumberOfPages =
MiFreeDescriptorLargest->
PageCount - 1;
00202
MiNextPhysicalPage =
MiFreeDescriptorLargest->
BasePage;
00203
00204
MiFreeDescriptorLowMem->
PageCount = 0;
00205
00206
return MiNextPhysicalPage++;
00207
00208 }
else {
00209
00210
MiOldFreeDescriptorCount =
MiFreeDescriptorLowMem->
PageCount;
00211
MiOldFreeDescriptorBase =
MiFreeDescriptorLowMem->
BasePage;
00212
00213
MiFreeDescriptor =
MiFreeDescriptorLowMem;
00214
MiNumberOfPages =
MiFreeDescriptorLowMem->
PageCount - 1;
00215
MiNextPhysicalPage =
MiFreeDescriptorLowMem->
BasePage;
00216
00217
MiFreeDescriptorNonPaged->
PageCount = 0;
00218
00219
return MiNextPhysicalPage++;
00220 }
00221 }
00222 }
00223
00224 BOOLEAN
00225 MiEnsureAvailablePagesInFreeDescriptor(
00226 IN PFN_NUMBER Pages,
00227 IN PFN_NUMBER MaxPage
00228 )
00229 {
00230
if ((
MiNumberOfPages < Pages) &&
00231 (
MiFreeDescriptor ==
MiFreeDescriptorNonPaged)) {
00232
00233
MiFreeDescriptor->
BasePage = (ULONG)
MiNextPhysicalPage;
00234
MiFreeDescriptor->
PageCount = (PFN_COUNT)
MiNumberOfPages;
00235
00236
if (
MiFreeDescriptor !=
MiFreeDescriptorLowMem) {
00237
00238
MiOldFreeDescriptorCount =
MiFreeDescriptorLowMem->
PageCount;
00239
MiOldFreeDescriptorBase =
MiFreeDescriptorLowMem->
BasePage;
00240
00241
MiFreeDescriptor =
MiFreeDescriptorLowMem;
00242
MiNumberOfPages =
MiFreeDescriptorLowMem->
PageCount;
00243
MiNextPhysicalPage =
MiFreeDescriptorLowMem->
BasePage;
00244
00245 }
else if (
MiFreeDescriptor !=
MiFreeDescriptorLargest) {
00246
00247
MiOldFreeDescriptorCount =
MiFreeDescriptorLargest->
PageCount;
00248
MiOldFreeDescriptorBase =
MiFreeDescriptorLargest->
BasePage;
00249
00250
MiFreeDescriptor =
MiFreeDescriptorLargest;
00251
MiNumberOfPages =
MiFreeDescriptorLargest->
PageCount;
00252
MiNextPhysicalPage =
MiFreeDescriptorLargest->
BasePage;
00253
00254 }
else {
00255
00256
KeBugCheckEx(INSTALL_MORE_MEMORY,
00257
MmNumberOfPhysicalPages,
00258
MmLowestPhysicalPage,
00259
MmHighestPhysicalPage,
00260 1);
00261 }
00262 }
00263
00264
if (MaxPage < (
MiFreeDescriptor->
BasePage + Pages)) {
00265
00266
return FALSE;
00267
00268 }
else {
00269
00270
return TRUE;
00271
00272 }
00273 }
00274
00275
00276
VOID
00277 MiInitMachineDependent (
00278 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00279 )
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 {
00308
PMMPFN BasePfn;
00309
PMMPFN BottomPfn;
00310
PMMPFN TopPfn;
00311 SIZE_T Range;
00312 PFN_NUMBER i;
00313 ULONG j;
00314 PFN_NUMBER PdePageNumber;
00315 PFN_NUMBER PdePage;
00316 PFN_NUMBER PageFrameIndex;
00317 PFN_NUMBER NextPhysicalPage;
00318 SPFN_NUMBER PfnAllocation;
00319 SPFN_NUMBER NumberOfPages;
00320 SIZE_T MaxPool;
00321
PEPROCESS CurrentProcess;
00322 PFN_NUMBER MostFreePage = 0;
00323 PFN_NUMBER MostFreeLowMem = 0;
00324 PFN_NUMBER MostFreeNonPaged = 0;
00325 PLIST_ENTRY NextMd;
00326
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
00327
MMPTE TempPte;
00328
PMMPTE PointerPde;
00329
PMMPTE PointerPte;
00330
PMMPTE StartPte;
00331
PMMPTE LastPte;
00332
PMMPTE EndPte;
00333
PMMPTE Pde;
00334
PMMPTE StartPde;
00335
PMMPTE StartPpe;
00336
PMMPTE EndPde;
00337
PMMPTE FirstPpe;
00338
PMMPFN Pfn1;
00339
PMMPFN Pfn2;
00340 ULONG First;
00341 KIRQL OldIrql;
00342 ULONG_PTR va;
00343 SIZE_T Kseg0Size = 0;
00344 PVOID NonPagedPoolStartVirtual;
00345 ULONG i1;
00346 ULONG i2;
00347 PFN_NUMBER PhysicalPages;
00348 ULONG_PTR HighestPageAddress;
00349 ULONG_PTR Kseg3VhptSize;
00350 PFN_NUMBER Kseg3VhptPn;
00351 ULONG_PTR size;
00352 ULONG_PTR PageSize;
00353 PFN_NUMBER KernelStart;
00354 PFN_NUMBER KernelEnd;
00355
00356
if (
InitializationPhase == 1) {
00357
00358
MiMakeKernelPagesPermanent(LoaderBlock);
00359
00360
return;
00361
00362 }
00363
00364
00365
00366
00367
00368
MiNtoskrnlPhysicalBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress;
00369
MiNtoskrnlVirtualBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].VirtualAddress;
00370
MiNtoskrnlPageShift = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PageSize;
00371
00372 KernelStart =
MiNtoskrnlPhysicalBase >>
PAGE_SHIFT;
00373 PageSize = (ULONG_PTR)1 <<
MiNtoskrnlPageShift;
00374 KernelEnd = KernelStart + (PageSize >>
PAGE_SHIFT);
00375
00376
00377
00378
00379
00380
MmDebugPte =
MiGetPteAddress(
MM_DEBUG_VA);
00381
00382
MmCrashDumpPte =
MiGetPteAddress(
MM_CRASH_DUMP_VA);
00383
00384
00385
00386
00387
00388 TempPte =
ValidKernelPte;
00389
00390
00391
00392
00393
00394
MiCheckMemoryDescriptorList(LoaderBlock);
00395
00396
00397
00398
00399
00400
00401
00402 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00403
00404
#if ADD_HIGH_MEMORY
00405
LoaderBlock->MemoryDescriptorListHead.Flink = &MiHighMemoryDescriptor.
ListEntry;
00406 MiHighMemoryDescriptor.
ListEntry.Flink = NextMd;
00407 MiHighMemoryDescriptor.
MemoryType = 5;
00408 MiHighMemoryDescriptor.
BasePage = 0x80000;
00409 MiHighMemoryDescriptor.
PageCount = 0x20000;
00410 NextMd = &MiHighMemoryDescriptor.
ListEntry;
00411
#endif
00412
00413
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00414
00415 MemoryDescriptor = CONTAINING_RECORD(NextMd,
00416
MEMORY_ALLOCATION_DESCRIPTOR,
00417 ListEntry);
00418
00419
00420
00421
00422
00423
if (MemoryDescriptor->
MemoryType !=
LoaderBad) {
00424
MmNumberOfPhysicalPages += MemoryDescriptor->
PageCount;
00425 }
00426
00427
if (MemoryDescriptor->
BasePage <
MmLowestPhysicalPage) {
00428
MmLowestPhysicalPage = MemoryDescriptor->
BasePage;
00429 }
00430
if ((MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount) >
00431
MmHighestPhysicalPage) {
00432
MmHighestPhysicalPage =
00433 MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount -1;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
if ((MemoryDescriptor->
MemoryType ==
LoaderFree) ||
00443 (MemoryDescriptor->
MemoryType ==
LoaderLoadedProgram) ||
00444 (MemoryDescriptor->
MemoryType ==
LoaderFirmwareTemporary) ||
00445 (MemoryDescriptor->
MemoryType ==
LoaderOsloaderStack)) {
00446
00447
if (MemoryDescriptor->
PageCount > MostFreePage) {
00448 MostFreePage = MemoryDescriptor->
PageCount;
00449
MiFreeDescriptorLargest = MemoryDescriptor;
00450 }
00451
00452
if (MemoryDescriptor->
BasePage <
_x256mbnp) {
00453
00454
00455
00456
00457
00458
if ((MostFreeLowMem < MemoryDescriptor->
PageCount) &&
00459 (MostFreeLowMem <
_x256mbnp - MemoryDescriptor->
BasePage)) {
00460
00461 MostFreeLowMem =
_x256mbnp - MemoryDescriptor->
BasePage;
00462
if (MemoryDescriptor->
PageCount < MostFreeLowMem) {
00463 MostFreeLowMem = MemoryDescriptor->
PageCount;
00464 }
00465
00466
MiFreeDescriptorLowMem = MemoryDescriptor;
00467 }
00468 }
00469
00470
if ((MemoryDescriptor->
BasePage >= KernelStart) &&
00471 (MemoryDescriptor->
PageCount > MostFreeNonPaged)) {
00472
00473 MostFreeNonPaged = MemoryDescriptor->
PageCount;
00474
MiFreeDescriptorNonPaged = MemoryDescriptor;
00475
00476 }
00477
00478 }
00479
00480
#if DBG
00481
if (
MiPrintMemoryDescriptors) {
00482
DbgPrint(
"MemoryType = %x\n", MemoryDescriptor->
MemoryType);
00483
DbgPrint(
"BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->
BasePage <<
PAGE_SHIFT);
00484
DbgPrint(
"PageCount = %x\n\n", MemoryDescriptor->
PageCount <<
PAGE_SHIFT);
00485 }
00486
#endif
00487
00488 NextMd = MemoryDescriptor->
ListEntry.Flink;
00489 }
00490
00491
MmHighestPossiblePhysicalPage =
MmHighestPhysicalPage;
00492
00493
00494
00495
00496
00497
00498
if (
MmNumberOfPhysicalPages <
_x16mbnp) {
00499
KeBugCheckEx (INSTALL_MORE_MEMORY,
00500
MmNumberOfPhysicalPages,
00501
MmLowestPhysicalPage,
00502
MmHighestPhysicalPage,
00503 2);
00504 }
00505
00506
00507
00508
00509
00510
00511
if (
MiFreeDescriptorNonPaged !=
NULL) {
00512
00513
MiFreeDescriptor =
MiFreeDescriptorNonPaged;
00514
00515 }
else if (
MiFreeDescriptorLowMem !=
NULL) {
00516
00517
MiFreeDescriptor =
MiFreeDescriptorLowMem;
00518
00519 }
else {
00520
00521
MiFreeDescriptor =
MiFreeDescriptorLargest;
00522 }
00523
00524
if (
MiFreeDescriptorLowMem ==
NULL) {
00525
00526
MiKseg0Mapping =
FALSE;
00527
00528 }
00529
00530
MiNextPhysicalPage =
MiFreeDescriptor->
BasePage;
00531
MiNumberOfPages =
MiFreeDescriptor->
PageCount;
00532
MiOldFreeDescriptorCount =
MiFreeDescriptor->
PageCount;
00533
MiOldFreeDescriptorBase =
MiFreeDescriptor->
BasePage;
00534
00535
00536
00537
00538
00539
if (
MiKseg0Mapping ==
TRUE) {
00540
00541
00542
MiKseg0Start =
KSEG0_ADDRESS(
MiNextPhysicalPage);
00543
00544 Kseg0Size =
MiNextPhysicalPage +
MiNumberOfPages;
00545
00546
if (Kseg0Size >
MM_PAGES_IN_KSEG0) {
00547 Kseg0Size =
MM_PAGES_IN_KSEG0 - (
_x16mbnp * 3);
00548 }
00549
00550 Kseg0Size = Kseg0Size <<
PAGE_SHIFT;
00551
00552 }
else {
00553
00554
MiKseg0Mapping =
FALSE;
00555 Kseg0Size = 0;
00556
00557 }
00558
00559
00560
00561
00562
00563
KeInitializeVhpt ((PVOID)PTA_BASE,
MiImplVirtualMsb -
PAGE_SHIFT +
PTE_SHIFT);
00564
00565
00566
00567
00568
00569
#if defined(KSEG_VHPT)
00570
HighestPageAddress = ((ULONG_PTR)
MmHighestPhysicalPage <<
PAGE_SHIFT);
00571
00572 HighestPageAddress = (HighestPageAddress + (ULONG_PTR)
X64K - 1) & ~((ULONG_PTR)
X64K - 1);
00573
00574 Kseg3VhptSize = HighestPageAddress >> 16 <<
PTE_SHIFT;
00575
00576 size = (Kseg3VhptSize-1) >> 12;
00577 PageSize = 12;
00578
00579
while (size != 0) {
00580 size = size >> 2;
00581 PageSize += 2;
00582 }
00583
00584 Kseg3VhptSize = (ULONG_PTR)1 << PageSize;
00585
00586 Kseg3VhptPages = (PFN_NUMBER)(Kseg3VhptSize >>
PAGE_SHIFT);
00587
00588
if ((
MiFreeDescriptor->
BasePage & (
_x16mbnp - 1)) != 0) {
00589
KeBugCheckEx (INSTALL_MORE_MEMORY,
00590
MmNumberOfPhysicalPages,
00591
MmLowestPhysicalPage,
00592
MmHighestPhysicalPage,
00593 3);
00594 }
00595
00596
MmKseg3VhptBase =
MiNextPhysicalPage;
00597
MiNextPhysicalPage += Kseg3VhptPages;
00598
MiNumberOfPages -= Kseg3VhptPages;
00599
00600
if (
MiNumberOfPages < 0) {
00601
00602
KeBugCheckEx(INSTALL_MORE_MEMORY,
00603
MmNumberOfPhysicalPages,
00604
MmLowestPhysicalPage,
00605
MmHighestPhysicalPage,
00606 4);
00607 }
00608
00609
#endif
00610
00611
00612
00613
00614
00615 PdePageNumber = (PFN_NUMBER)LoaderBlock->u.Ia64.PdrPage;
00616
00617
MmSystemParentTablePage =
MiGetNextPhysicalPage();
00618
00619 RtlZeroMemory(KSEG_ADDRESS(
MmSystemParentTablePage),
PAGE_SIZE);
00620
00621 TempPte.
u.Hard.PageFrameNumber =
MmSystemParentTablePage;
00622
00623
MiSystemSelfMappedPte = TempPte;
00624
00625 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)
PDE_KTBASE, DTR_KTBASE_INDEX_TMP);
00626
00627
00628
00629
00630
00631 PointerPte =
MiGetPteAddress(
PDE_KTBASE);
00632
00633
MI_WRITE_VALID_PTE(PointerPte, TempPte);
00634
00635
00636
00637
00638
00639 PointerPte =
MiGetPteAddress(PDE_KBASE);
00640
00641 TempPte.u.Hard.PageFrameNumber = PdePageNumber;
00642
00643
MI_WRITE_VALID_PTE(PointerPte, TempPte);
00644
00645
00646
00647
00648
00649 NextPhysicalPage =
MiGetNextPhysicalPage();
00650
00651 RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00652
00653 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00654
00655
INITIALIZE_DIRECTORY_TABLE_BASE
00656 (&(
PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]), NextPhysicalPage);
00657
00658
MiUserSelfMappedPte = TempPte;
00659
00660 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX_TMP);
00661
00662
00663
00664
00665
00666 PointerPte =
MiGetPteAddress(PDE_UTBASE);
00667
00668
MI_WRITE_VALID_PTE(PointerPte, TempPte);
00669
00670
00671
00672
00673
00674 NextPhysicalPage =
MiGetNextPhysicalPage();
00675
00676 RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00677
00678 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00679
00680
INITIALIZE_DIRECTORY_TABLE_BASE
00681 (&(
PsGetCurrentProcess()->Pcb.SessionParentBase), NextPhysicalPage);
00682
00683 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_STBASE, DTR_STBASE_INDEX);
00684
00685
00686
00687
00688
00689 PointerPte =
MiGetPteAddress(PDE_STBASE);
00690
00691
MI_WRITE_VALID_PTE(PointerPte, TempPte);
00692
00693
00694
00695
00696
00697
#if defined(KSEG_VHPT)
00698
va =
KSEG0_ADDRESS(
MmKseg3VhptBase);
00699
00700 RtlZeroMemory((PVOID)va, Kseg3VhptSize);
00701
00702 TempPte.u.Hard.PageFrameNumber =
MmKseg3VhptBase;
00703
00704 PointerPte =
MiGetKSegPteAddress(KSEG3_BASE);
00705
00706 KeFillFixedLargeEntryTb((PHARDWARE_PTE)&TempPte,
00707 (PVOID)PointerPte,
00708 PageSize,
00709 DTR_KSEG3_INDEX);
00710
00711
MmKseg3VhptPs = PageSize;
00712
#endif
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
if ((
MmSizeOfNonPagedPoolInBytes >>
PAGE_SHIFT) >
00725 (7 * (
MmNumberOfPhysicalPages << 3))) {
00726
00727
00728
00729
00730
00731
MmSizeOfNonPagedPoolInBytes = 0;
00732 }
00733
00734
if (
MmSizeOfNonPagedPoolInBytes <
MmMinimumNonPagedPoolSize) {
00735
00736
00737
00738
00739
00740
00741
00742
MmSizeOfNonPagedPoolInBytes =
MmMinimumNonPagedPoolSize;
00743
00744
MmSizeOfNonPagedPoolInBytes +=
00745 ((
MmNumberOfPhysicalPages -
_x16mbnp)/
_x1mbnp) *
00746
MmMinAdditionNonPagedPoolPerMb;
00747 }
00748
00749
if (
MmSizeOfNonPagedPoolInBytes >
MM_MAX_INITIAL_NONPAGED_POOL) {
00750
MmSizeOfNonPagedPoolInBytes =
MM_MAX_INITIAL_NONPAGED_POOL;
00751 }
00752
00753
00754
00755
00756
00757
MmSizeOfNonPagedPoolInBytes &= ~(
PAGE_SIZE - 1);
00758
00759
00760
00761
00762
00763
if (
MmMaximumNonPagedPoolInBytes == 0) {
00764
00765
00766
00767
00768
00769
00770
00771
MmMaximumNonPagedPoolInBytes =
MmDefaultMaximumNonPagedPool;
00772
00773
00774
00775
00776
00777
MmMaximumNonPagedPoolInBytes += (
MmHighestPhysicalPage *
sizeof(
MMPFN)) & ~(
PAGE_SIZE-1);
00778
00779
MmMaximumNonPagedPoolInBytes +=
00780 ((
MmNumberOfPhysicalPages -
_x16mbnp)/
_x1mbnp) *
00781
MmMaxAdditionNonPagedPoolPerMb;
00782
00783 }
00784
00785 MaxPool =
MmSizeOfNonPagedPoolInBytes +
PAGE_SIZE * 16 +
00786 ((
MmHighestPhysicalPage *
sizeof(
MMPFN)) & ~(
PAGE_SIZE -1));
00787
00788
if (
MmMaximumNonPagedPoolInBytes < MaxPool) {
00789
MmMaximumNonPagedPoolInBytes = MaxPool;
00790 }
00791
00792
if (
MmMaximumNonPagedPoolInBytes >
MM_MAX_ADDITIONAL_NONPAGED_POOL) {
00793
MmMaximumNonPagedPoolInBytes =
MM_MAX_ADDITIONAL_NONPAGED_POOL;
00794 }
00795
00796
MmNonPagedPoolStart = (PVOID)((ULONG_PTR)
MmNonPagedPoolEnd
00797 -
MmMaximumNonPagedPoolInBytes);
00798
00799
MmNonPagedPoolStart = (PVOID)
PAGE_ALIGN(
MmNonPagedPoolStart);
00800
00801
MmPageAlignedPoolBase[
NonPagedPool] =
MmNonPagedPoolStart;
00802
00803
00804
00805
00806
00807
00808
MmNonPagedSystemStart = (PVOID)(((ULONG_PTR)
MmNonPagedPoolStart -
00809 ((
MmNumberOfSystemPtes + 1) *
PAGE_SIZE)) &
00810 (~
PAGE_DIRECTORY2_MASK));
00811
00812
if (
MmNonPagedSystemStart <
MM_LOWEST_NONPAGED_SYSTEM_START) {
00813
MmNonPagedSystemStart =
MM_LOWEST_NONPAGED_SYSTEM_START;
00814
MmNumberOfSystemPtes = (ULONG)(((ULONG_PTR)
MmNonPagedPoolStart -
00815 (ULONG_PTR)
MmNonPagedSystemStart) >>
PAGE_SHIFT)-1;
00816
ASSERT (
MmNumberOfSystemPtes > 1000);
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 TempPte =
ValidPdePde;
00836 StartPde =
MiGetPdeAddress(
HYPER_SPACE);
00837 StartPpe =
MiGetPpeAddress(
HYPER_SPACE);
00838 EndPde = StartPde;
00839 First = (StartPpe->
u.Hard.Valid == 0) ?
TRUE :
FALSE;
00840
00841
while (StartPde <= EndPde) {
00842
00843
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00844 First =
FALSE;
00845 StartPpe =
MiGetPteAddress(StartPde);
00846
if (StartPpe->
u.Hard.Valid == 0) {
00847
ASSERT (StartPpe->
u.Long == 0);
00848 NextPhysicalPage =
MiGetNextPhysicalPage();
00849 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00850 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00851
MI_WRITE_VALID_PTE(StartPpe, TempPte);
00852 }
00853 }
00854 NextPhysicalPage =
MiGetNextPhysicalPage();
00855 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00856 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00857
MI_WRITE_VALID_PTE(StartPde, TempPte);
00858 StartPde += 1;
00859 }
00860
00861
00862
00863
00864
00865
00866 TempPte =
ValidKernelPte;
00867 StartPde =
MiGetPdeAddress(
MmNonPagedSystemStart);
00868 StartPpe =
MiGetPpeAddress(
MmNonPagedSystemStart);
00869 EndPde =
MiGetPdeAddress((ULONG_PTR)
MmNonPagedPoolEnd - 1);
00870 First = (StartPpe->
u.Hard.Valid == 0) ?
TRUE :
FALSE;
00871
00872
while (StartPde <= EndPde) {
00873
00874
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00875 First =
FALSE;
00876 StartPpe =
MiGetPteAddress(StartPde);
00877
if (StartPpe->
u.Hard.Valid == 0) {
00878 NextPhysicalPage =
MiGetNextPhysicalPage();
00879 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00880 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00881
MI_WRITE_VALID_PTE(StartPpe, TempPte);
00882 }
00883 }
00884
00885
if (StartPde->u.Hard.Valid == 0) {
00886 NextPhysicalPage =
MiGetNextPhysicalPage();
00887 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00888 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00889
MI_WRITE_VALID_PTE(StartPde, TempPte);
00890 }
00891 StartPde += 1;
00892 }
00893
00894 NonPagedPoolStartVirtual =
MmNonPagedPoolStart;
00895
00896
00897
00898
00899
MiBuildPageTableForLoaderMemory(LoaderBlock);
00900
00901
MiRemoveLoaderSuperPages(LoaderBlock);
00902
00903
00904
00905
00906
00907
00908 KiFlushFixedDataTb(
FALSE, (PVOID)
PDE_KTBASE);
00909 KiFlushFixedDataTb(
FALSE, (PVOID)PDE_UTBASE);
00910 KeFillFixedEntryTb((PHARDWARE_PTE)&
MiSystemSelfMappedPte, (PVOID)
PDE_KTBASE, DTR_KTBASE_INDEX);
00911 KeFillFixedEntryTb((PHARDWARE_PTE)&
MiUserSelfMappedPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX);
00912
00913
if (
MiKseg0Mapping ==
TRUE) {
00914
00915
00916
00917
00918
00919 StartPde =
MiGetPdeAddress(
MiKseg0Start);
00920 EndPde =
MiGetPdeAddress((PCHAR)
KSEG0_BASE + Kseg0Size);
00921
00922
while (StartPde <= EndPde) {
00923
00924
if (StartPde->u.Hard.Valid == 0) {
00925 NextPhysicalPage =
MiGetNextPhysicalPage();
00926 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
00927 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00928
MI_WRITE_VALID_PTE(StartPde, TempPte);
00929 }
00930 StartPde++;
00931 }
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
if (
MiKseg0Mapping ==
TRUE) {
00945
00946
00947
00948
00949
00950
MiKseg0Mapping =
00951
MiEnsureAvailablePagesInFreeDescriptor(
BYTES_TO_PAGES(
MmSizeOfNonPagedPoolInBytes),
00952
MM_PAGES_IN_KSEG0);
00953
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963 PointerPte =
MiGetPteAddress(
MmNonPagedPoolStart);
00964 LastPte =
MiGetPteAddress((PCHAR)
MmNonPagedPoolStart +
00965
MmSizeOfNonPagedPoolInBytes - 1);
00966
00967
while (PointerPte <= LastPte) {
00968 NextPhysicalPage =
MiGetNextPhysicalPage();
00969 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
00970
MI_WRITE_VALID_PTE(PointerPte, TempPte);
00971 PointerPte++;
00972 }
00973
00974
00975
00976
00977
00978
00979
while (!
MiIsPteOnPdeBoundary (PointerPte)) {
00980
MI_WRITE_INVALID_PTE(PointerPte,
ZeroKernelPte);
00981 PointerPte += 1;
00982 }
00983
00984
00985
00986
00987
00988
00989
if (
MiKseg0Mapping ==
TRUE) {
00990
00991
00992
00993
00994
00995
00996
00997 PointerPte =
MiGetPteAddress (
MmNonPagedPoolStart);
00998
MmNonPagedPoolStart =
KSEG0_ADDRESS(PointerPte->u.Hard.PageFrameNumber);
00999
MmSubsectionBase =
KSEG0_BASE;
01000
01001 StartPte =
MiGetPteAddress(
MmNonPagedPoolStart);
01002 LastPte =
MiGetPteAddress((PCHAR)
MmNonPagedPoolStart +
01003
MmSizeOfNonPagedPoolInBytes - 1);
01004
01005
MiKseg0Start =
MiGetVirtualAddressMappedByPte(StartPte);
01006
01007
while (StartPte <= LastPte) {
01008
01009
01010
01011
01012
01013
01014
MI_WRITE_VALID_PTE(StartPte, *PointerPte);
01015 StartPte++;
01016 PointerPte++;
01017 }
01018
01019
MiKseg0End =
MiGetVirtualAddressMappedByPte(LastPte);
01020
01021 }
else {
01022
01023
MiKseg0Mapping =
FALSE;
01024
MmSubsectionBase = 0;
01025
01026 }
01027
01028
01029
01030
01031
01032
01033
MmSubsectionTopPage = 0;
01034
01035
01036
MmNonPagedPoolExpansionStart = (PVOID)((PCHAR)NonPagedPoolStartVirtual +
01037
MmSizeOfNonPagedPoolInBytes);
01038
01039
MmPageAlignedPoolBase[
NonPagedPool] =
MmNonPagedPoolStart;
01040
01041
01042
01043
01044
01045
01046
MiInitializeNonPagedPool ();
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
MmSecondaryColors =
MmSecondaryColors >>
PAGE_SHIFT;
01063
01064
if (
MmSecondaryColors == 0) {
01065
MmSecondaryColors =
MM_SECONDARY_COLORS_DEFAULT;
01066 }
else {
01067
01068
01069
01070
01071
01072
if (((
MmSecondaryColors & (
MmSecondaryColors -1)) != 0) ||
01073 (
MmSecondaryColors <
MM_SECONDARY_COLORS_MIN) ||
01074 (
MmSecondaryColors >
MM_SECONDARY_COLORS_MAX)) {
01075
MmSecondaryColors =
MM_SECONDARY_COLORS_DEFAULT;
01076 }
01077 }
01078
01079
MmSecondaryColorMask =
MmSecondaryColors - 1;
01080
01081
01082
01083
01084
01085
01086
01087 PfnAllocation = 1 + ((((
MmHighestPhysicalPage + 1) *
sizeof(
MMPFN)) +
01088 (
MmSecondaryColors *
sizeof(
MMCOLOR_TABLES)*2))
01089 >>
PAGE_SHIFT);
01090
01091
01092
if ((
MmHighestPhysicalPage <
_x4gbnp) &&
01093 (
MiKseg0Mapping ==
TRUE) &&
01094 (
MiEnsureAvailablePagesInFreeDescriptor(PfnAllocation,
01095
MM_PAGES_IN_KSEG0))) {
01096
01097
01098
01099
01100
01101
01102
01103
MmPfnDatabase = (
PMMPFN)
KSEG0_ADDRESS(
MiNextPhysicalPage);
01104
01105 StartPte =
MiGetPteAddress(
MmPfnDatabase);
01106 LastPte =
MiGetPteAddress((PCHAR)
MmPfnDatabase + (PfnAllocation <<
PAGE_SHIFT) - 1);
01107
01108
while (StartPte <= LastPte) {
01109 TempPte.u.Hard.PageFrameNumber =
MiGetNextPhysicalPage();
01110
MI_WRITE_VALID_PTE(StartPte, TempPte);
01111 StartPte++;
01112 }
01113
01114 RtlZeroMemory(
MmPfnDatabase, PfnAllocation *
PAGE_SIZE);
01115
MiKseg0End =
MiGetVirtualAddressMappedByPte(LastPte);
01116
01117 }
else {
01118
01119
01120
01121
01122
01123
01124
MmPfnDatabase = (
PMMPFN)
MM_PFN_DATABASE_START;
01125
01126
01127
01128
01129
01130
01131
01132
01133 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01134
01135
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01136
01137 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01138
MEMORY_ALLOCATION_DESCRIPTOR,
01139 ListEntry);
01140
01141 PointerPte =
MiGetPteAddress (
MI_PFN_ELEMENT(
01142 MemoryDescriptor->
BasePage));
01143
01144 LastPte =
MiGetPteAddress (((PCHAR)(
MI_PFN_ELEMENT(
01145 MemoryDescriptor->
BasePage +
01146 MemoryDescriptor->
PageCount))) - 1);
01147
01148 First =
TRUE;
01149
01150
while (PointerPte <= LastPte) {
01151
01152
if (First ==
TRUE ||
MiIsPteOnPpeBoundary(PointerPte)) {
01153 StartPpe =
MiGetPdeAddress(PointerPte);
01154
if (StartPpe->
u.Hard.Valid == 0) {
01155
ASSERT (StartPpe->
u.Long == 0);
01156 NextPhysicalPage =
MiGetNextPhysicalPage();
01157 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
01158 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
01159
MI_WRITE_VALID_PTE(StartPpe, TempPte);
01160 }
01161 }
01162
01163
if ((First ==
TRUE) ||
MiIsPteOnPdeBoundary(PointerPte)) {
01164 First =
FALSE;
01165 StartPde =
MiGetPteAddress(PointerPte);
01166
if (StartPde->u.Hard.Valid == 0) {
01167 NextPhysicalPage =
MiGetNextPhysicalPage();
01168 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
01169 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
01170
MI_WRITE_VALID_PTE(StartPde, TempPte);
01171 }
01172 }
01173
01174
if (PointerPte->u.Hard.Valid == 0) {
01175 NextPhysicalPage =
MiGetNextPhysicalPage();
01176 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
01177 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
01178
MI_WRITE_VALID_PTE(PointerPte, TempPte);
01179 }
01180
01181 PointerPte++;
01182 }
01183 NextMd = MemoryDescriptor->
ListEntry.Flink;
01184 }
01185 }
01186
01187
if (
MiKseg0Mapping ==
TRUE) {
01188
01189
01190
01191
01192
01193
MiConvertToSuperPages(
MiKseg0Start,
01194
MiKseg0End,
01195
_x1mb,
01196
MM_PTE_1MB_PAGE);
01197
01198
MiConvertToSuperPages(
MiKseg0Start,
01199
MiKseg0End,
01200
_x4mb,
01201
MM_PTE_4MB_PAGE);
01202
01203
MiConvertToSuperPages(
MiKseg0Start,
01204
MiKseg0End,
01205
_x16mb,
01206
MM_PTE_16MB_PAGE);
01207
01208
MiConvertToSuperPages(
MiKseg0Start,
01209
MiKseg0End,
01210
_x64mb,
01211
MM_PTE_64MB_PAGE);
01212
01213
MiConvertToSuperPages(
MiKseg0Start,
01214
MiKseg0End,
01215
_x256mb,
01216
MM_PTE_256MB_PAGE);
01217
01218 }
01219
01220
01221
01222
01223
01224
01225
MmFreePagesByColor[0] = (
PMMCOLOR_TABLES)
01226 &
MmPfnDatabase[
MmHighestPhysicalPage + 1];
01227
01228
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
01229
01230
01231
01232
01233
01234
if (!
MI_IS_PHYSICAL_ADDRESS(
MmFreePagesByColor[0])) {
01235 PointerPte =
MiGetPteAddress (&
MmFreePagesByColor[0][0]);
01236
01237 LastPte =
MiGetPteAddress (
01238 (PVOID)((PCHAR)&
MmFreePagesByColor[1][
MmSecondaryColors] - 1));
01239
01240
while (PointerPte <= LastPte) {
01241
if (PointerPte->u.Hard.Valid == 0) {
01242 NextPhysicalPage =
MiGetNextPhysicalPage();
01243 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
01244 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
01245
MI_WRITE_VALID_PTE(PointerPte, TempPte);
01246 }
01247 PointerPte++;
01248 }
01249 }
01250
01251
for (i = 0; i <
MmSecondaryColors; i++) {
01252
MmFreePagesByColor[
ZeroedPageList][i].
Flink =
MM_EMPTY_LIST;
01253
MmFreePagesByColor[
FreePageList][i].
Flink =
MM_EMPTY_LIST;
01254 }
01255
01256
#if MM_MAXIMUM_NUMBER_OF_COLORS > 1
01257
for (i = 0; i <
MM_MAXIMUM_NUMBER_OF_COLORS; i++) {
01258
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
ListName =
ZeroedPageList;
01259
MmFreePagesByPrimaryColor[
FreePageList][i].
ListName =
FreePageList;
01260
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
Flink =
MM_EMPTY_LIST;
01261
MmFreePagesByPrimaryColor[
FreePageList][i].
Flink =
MM_EMPTY_LIST;
01262
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
Blink =
MM_EMPTY_LIST;
01263
MmFreePagesByPrimaryColor[
FreePageList][i].
Blink =
MM_EMPTY_LIST;
01264 }
01265
#endif
01266
01267
01268
01269
01270
01271
01272 StartPde =
MiGetPdeAddress (
HYPER_SPACE);
01273 StartPpe =
MiGetPpeAddress (
HYPER_SPACE);
01274 EndPde =
MiGetPdeAddress(
HYPER_SPACE_END);
01275 First = (StartPpe->
u.Hard.Valid == 0) ?
TRUE :
FALSE;
01276
01277
while (StartPde <= EndPde) {
01278
01279
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
01280 First =
FALSE;
01281 StartPpe =
MiGetPteAddress(StartPde);
01282
if (StartPpe->
u.Hard.Valid == 0) {
01283 StartPpe += 1;
01284 StartPde =
MiGetVirtualAddressMappedByPte (StartPpe);
01285
continue;
01286 }
01287
01288 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPpe);
01289
01290 Pfn1 =
MI_PFN_ELEMENT(PdePage);
01291 Pfn1->
PteFrame =
MmSystemParentTablePage;
01292 Pfn1->
PteAddress = StartPde;
01293 Pfn1->
u2.ShareCount += 1;
01294 Pfn1->
u3.e2.ReferenceCount = 1;
01295 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01296 Pfn1->
u3.e1.PageColor =
01297
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe));
01298 }
01299
01300
01301
if (StartPde->u.Hard.Valid == 1) {
01302 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPde);
01303 Pfn1 =
MI_PFN_ELEMENT(PdePage);
01304 PointerPde =
MiGetPteAddress(StartPde);
01305 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPde);
01306 Pfn1->
PteAddress = StartPde;
01307 Pfn1->
u2.ShareCount += 1;
01308 Pfn1->
u3.e2.ReferenceCount = 1;
01309 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01310 Pfn1->
u3.e1.PageColor =
01311
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde));
01312
01313 PointerPte =
MiGetVirtualAddressMappedByPte(StartPde);
01314
for (j = 0 ; j <
PTE_PER_PAGE; j++) {
01315
if (PointerPte->u.Hard.Valid == 1) {
01316
01317 Pfn1->
u2.ShareCount += 1;
01318
01319
if (PointerPte->u.Hard.PageFrameNumber <=
01320
MmHighestPhysicalPage) {
01321 Pfn2 =
MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
01322 Pfn2->
PteFrame = PdePage;
01323 Pfn2->
PteAddress = PointerPte;
01324 Pfn2->
u2.ShareCount += 1;
01325 Pfn2->
u3.e2.ReferenceCount = 1;
01326 Pfn2->
u3.e1.PageLocation =
ActiveAndValid;
01327 Pfn2->
u3.e1.PageColor =
01328
MI_GET_COLOR_FROM_SECONDARY(
01329
MI_GET_PAGE_COLOR_FROM_PTE (
01330 PointerPte));
01331 }
01332 }
01333 PointerPte += 1;
01334 }
01335 }
01336
01337 StartPde++;
01338 }
01339
01340
01341
01342
01343
01344 StartPde =
MiGetPdeAddress (KADDRESS_BASE);
01345 StartPpe =
MiGetPpeAddress (KADDRESS_BASE);
01346 EndPde =
MiGetPdeAddress(
MM_SYSTEM_SPACE_END);
01347 First = (StartPpe->
u.Hard.Valid == 0) ?
TRUE :
FALSE;
01348
01349
while (StartPde <= EndPde) {
01350
01351
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
01352 First =
FALSE;
01353 StartPpe =
MiGetPteAddress(StartPde);
01354
if (StartPpe->
u.Hard.Valid == 0) {
01355 StartPpe += 1;
01356 StartPde =
MiGetVirtualAddressMappedByPte (StartPpe);
01357
continue;
01358 }
01359
01360 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPpe);
01361
01362 Pfn1 =
MI_PFN_ELEMENT(PdePage);
01363 Pfn1->
PteFrame =
MmSystemParentTablePage;
01364 Pfn1->
PteAddress = StartPde;
01365 Pfn1->
u2.ShareCount += 1;
01366 Pfn1->
u3.e2.ReferenceCount = 1;
01367 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01368 Pfn1->
u3.e1.PageColor =
01369
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe));
01370 }
01371
01372
if (StartPde->u.Hard.Valid == 1) {
01373 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPde);
01374 Pfn1 =
MI_PFN_ELEMENT(PdePage);
01375 PointerPde =
MiGetPteAddress(StartPde);
01376 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPde);
01377 Pfn1->
PteAddress = StartPde;
01378 Pfn1->
u2.ShareCount += 1;
01379 Pfn1->
u3.e2.ReferenceCount = 1;
01380 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01381 Pfn1->
u3.e1.PageColor =
01382
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde));
01383
01384 PointerPte =
MiGetVirtualAddressMappedByPte(StartPde);
01385
for (j = 0 ; j <
PTE_PER_PAGE; j++) {
01386
if (PointerPte->u.Hard.Valid == 1) {
01387
01388 Pfn1->
u2.ShareCount += 1;
01389
01390
if (PointerPte->u.Hard.PageFrameNumber <=
01391
MmHighestPhysicalPage) {
01392 Pfn2 =
MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
01393 Pfn2->
PteFrame = PdePage;
01394 Pfn2->
PteAddress = PointerPte;
01395 Pfn2->
u2.ShareCount += 1;
01396 Pfn2->
u3.e2.ReferenceCount = 1;
01397 Pfn2->
u3.e1.PageLocation =
ActiveAndValid;
01398 Pfn2->
u3.e1.PageColor =
01399
MI_GET_COLOR_FROM_SECONDARY(
01400
MI_GET_PAGE_COLOR_FROM_PTE (
01401 PointerPte));
01402 }
01403 }
01404 PointerPte += 1;
01405 }
01406 }
01407
01408 StartPde++;
01409 }
01410
01411
01412
01413
01414
01415
01416
01417 Pfn1 = &
MmPfnDatabase[
MmLowestPhysicalPage];
01418
if (Pfn1->
u3.e2.ReferenceCount == 0) {
01419
01420
01421
01422
01423
01424
01425 Pde =
MiGetPdeAddress (KADDRESS_BASE + 0xb0000000);
01426 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(Pde);
01427 Pfn1->
PteFrame = PdePageNumber;
01428 Pfn1->
PteAddress = Pde;
01429 Pfn1->
u2.ShareCount += 1;
01430 Pfn1->
u3.e2.ReferenceCount = 1;
01431 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01432 Pfn1->
u3.e1.PageColor =
MI_GET_COLOR_FROM_SECONDARY(
01433
MI_GET_PAGE_COLOR_FROM_PTE (Pde));
01434 }
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
MiFreeDescriptor->
PageCount -=
01445 (PFN_COUNT)(
MiNextPhysicalPage -
MiOldFreeDescriptorBase);
01446
01447
01448
01449
01450
01451
01452
MiFreeDescriptor->
BasePage = (ULONG)
MiNextPhysicalPage;
01453
01454
01455
01456
01457
01458
01459
if (
MiFreeDescriptorNonPaged !=
NULL) {
01460
01461
if (
MiFreeDescriptorNonPaged->
BasePage > KernelEnd) {
01462
01463
MiWasteStart = KernelEnd;
01464
MiWasteEnd = KernelEnd;
01465
01466
01467 }
else if ((
MiFreeDescriptorNonPaged->
BasePage +
01468
MiFreeDescriptorNonPaged->
PageCount) > KernelEnd) {
01469
01470
MiWasteStart =
MiFreeDescriptorNonPaged->
BasePage;
01471
MiWasteEnd = KernelEnd;
01472
01473
MiFreeDescriptorNonPaged->
PageCount -=
01474 (PFN_COUNT) (KernelEnd -
MiFreeDescriptorNonPaged->
BasePage);
01475
01476
MiFreeDescriptorNonPaged->
BasePage = (ULONG) KernelEnd;
01477
01478 }
else if (
MiFreeDescriptorNonPaged->
PageCount != 0) {
01479
01480
MiWasteStart =
MiFreeDescriptorNonPaged->
BasePage;
01481
MiWasteEnd =
MiWasteStart +
MiFreeDescriptorNonPaged->
PageCount;
01482
MiFreeDescriptorNonPaged->
PageCount = 0;
01483
01484 }
01485 }
01486
01487 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01488
01489
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01490
01491 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01492
MEMORY_ALLOCATION_DESCRIPTOR,
01493 ListEntry);
01494
01495 i = MemoryDescriptor->
PageCount;
01496 NextPhysicalPage = MemoryDescriptor->
BasePage;
01497
01498
switch (MemoryDescriptor->
MemoryType) {
01499
case LoaderBad:
01500
while (i != 0) {
01501
MiInsertPageInList (
MmPageLocationList[
BadPageList],
01502 NextPhysicalPage);
01503 i -= 1;
01504 NextPhysicalPage += 1;
01505 }
01506
break;
01507
01508
case LoaderFree:
01509
case LoaderLoadedProgram:
01510
case LoaderFirmwareTemporary:
01511
case LoaderOsloaderStack:
01512
01513 Pfn1 =
MI_PFN_ELEMENT (NextPhysicalPage);
01514
while (i != 0) {
01515
if (Pfn1->
u3.e2.ReferenceCount == 0) {
01516
01517
01518
01519
01520
01521
01522 Pfn1->
PteAddress = KSEG_ADDRESS (NextPhysicalPage);
01523
MiInsertPageInList (
MmPageLocationList[
FreePageList],
01524 NextPhysicalPage);
01525 }
01526 Pfn1++;
01527 i -= 1;
01528 NextPhysicalPage += 1;
01529 }
01530
break;
01531
01532
default:
01533
01534 PointerPte = KSEG_ADDRESS(NextPhysicalPage);
01535 Pfn1 =
MI_PFN_ELEMENT (NextPhysicalPage);
01536
while (i != 0) {
01537
01538
01539
01540
01541
01542
if (Pfn1->
u3.e2.ReferenceCount == 0) {
01543 Pfn1->
PteFrame = PdePageNumber;
01544 Pfn1->
PteAddress = PointerPte;
01545 Pfn1->
u2.ShareCount += 1;
01546 Pfn1->
u3.e2.ReferenceCount = 1;
01547 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01548 Pfn1->
u3.e1.PageColor =
MI_GET_COLOR_FROM_SECONDARY(
01549
MI_GET_PAGE_COLOR_FROM_PTE (
01550 PointerPte));
01551 }
01552 Pfn1++;
01553 i -= 1;
01554 NextPhysicalPage += 1;
01555 PointerPte += 1;
01556 }
01557
break;
01558 }
01559
01560 NextMd = MemoryDescriptor->
ListEntry.Flink;
01561 }
01562
01563
if (
MI_IS_PHYSICAL_ADDRESS(
MmPfnDatabase) ==
FALSE) {
01564
01565
01566
01567
01568
01569 PointerPte =
MiGetPteAddress (&
MmPfnDatabase[
MmLowestPhysicalPage]);
01570 Pfn1 =
MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
01571 Pfn1->
u3.e1.StartOfAllocation = 1;
01572
01573
01574
01575
01576
01577 PointerPte =
MiGetPteAddress (&
MmPfnDatabase[
MmHighestPhysicalPage]);
01578 Pfn1 =
MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
01579 Pfn1->
u3.e1.EndOfAllocation = 1;
01580
01581 }
else {
01582
01583
01584
01585
01586
01587
01588 PageFrameIndex =
MI_CONVERT_PHYSICAL_TO_PFN (
MmPfnDatabase);
01589 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
01590
do {
01591 Pfn1->
PteAddress = KSEG_ADDRESS(PageFrameIndex);
01592 Pfn1->
u3.e1.PageColor = 0;
01593 Pfn1->
u3.e2.ReferenceCount += 1;
01594 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01595 PageFrameIndex += 1;
01596 Pfn1 += 1;
01597 PfnAllocation -= 1;
01598 }
while (PfnAllocation != 0);
01599
01600
01601
01602
01603
01604
#if 0
01605
01606
01607
01608
01609 BottomPfn =
MI_PFN_ELEMENT(
MmHighestPhysicalPage);
01610
do {
01611
01612
01613
01614
01615
01616
01617
01618
if (((ULONG_PTR)BottomPfn & (
PAGE_SIZE - 1)) != 0) {
01619 BasePfn = (
PMMPFN)((ULONG_PTR)BottomPfn & ~(
PAGE_SIZE - 1));
01620 TopPfn = BottomPfn + 1;
01621
01622 }
else {
01623 BasePfn = (
PMMPFN)((ULONG_PTR)BottomPfn -
PAGE_SIZE);
01624 TopPfn = BottomPfn;
01625 }
01626
01627
while (BottomPfn > BasePfn) {
01628 BottomPfn -= 1;
01629 }
01630
01631
01632
01633
01634
01635
01636
01637
01638 Range = (ULONG_PTR)TopPfn - (ULONG_PTR)BottomPfn;
01639
if (
RtlCompareMemoryUlong((PVOID)BottomPfn, Range, 0) == Range) {
01640
01641
01642
01643
01644
01645
01646 PageFrameIndex =
MI_CONVERT_PHYSICAL_TO_PFN (BasePfn);
01647 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
01648
01649
ASSERT (Pfn1->
u3.e2.ReferenceCount == 1);
01650
ASSERT (Pfn1->
PteAddress == KSEG_ADDRESS(PageFrameIndex));
01651 Pfn1->
u3.e2.ReferenceCount = 0;
01652 PfnAllocation += 1;
01653 Pfn1->
PteAddress = (
PMMPTE)((ULONG_PTR)PageFrameIndex <<
PTE_SHIFT);
01654 Pfn1->
u3.e1.PageColor = 0;
01655
MiInsertPageInList(
MmPageLocationList[
FreePageList],
01656 PageFrameIndex);
01657 }
01658
01659 }
while (BottomPfn >
MmPfnDatabase);
01660
#endif
01661
01662 }
01663
01664
01665
01666
01667
01668
01669
01670
if (
MI_IS_PHYSICAL_ADDRESS(
MmNonPagedMustSucceed)) {
01671 Pfn1 =
MI_PFN_ELEMENT(
MI_CONVERT_PHYSICAL_TO_PFN (
MmNonPagedMustSucceed));
01672 }
else {
01673 PointerPte =
MiGetPteAddress(
MmNonPagedMustSucceed);
01674 Pfn1 =
MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
01675 }
01676
01677 i =
MmSizeOfNonPagedMustSucceed;
01678
while ((LONG)i > 0) {
01679 Pfn1->
u3.e1.StartOfAllocation = 1;
01680 Pfn1->
u3.e1.EndOfAllocation = 1;
01681 i -=
PAGE_SIZE;
01682 Pfn1 += 1;
01683 }
01684
01685
#if 0
01686
01687
01688
01689
01690
01691
MiFreeDescriptor->
PageCount = (ULONG)
MiOldFreeDescriptorCount;
01692
01693
01694
01695
01696
01697
01698
MiFreeDescriptor->
BasePage = (ULONG)
MiOldFreeDescriptorBase;
01699
01700
#endif
01701
01702
01703
KeInitializeSpinLock (&
MmSystemSpaceLock);
01704
01705
KeInitializeSpinLock (&
MmPfnLock);
01706
01707
01708
01709
01710
01711
01712 PointerPte =
MiGetPteAddress (
MmNonPagedSystemStart);
01713
ASSERT (((ULONG_PTR)PointerPte & (
PAGE_SIZE - 1)) == 0);
01714
01715
MmNumberOfSystemPtes = (ULONG)(
MiGetPteAddress(NonPagedPoolStartVirtual) - PointerPte - 1);
01716
01717
MiInitializeSystemPtes (PointerPte,
MmNumberOfSystemPtes,
SystemPteSpace);
01718
01719
01720
01721
01722
01723
InitializePool(
NonPagedPool,0);
01724
01725
01726
01727
01728
01729
01730
01731
MmFirstReservedMappingPte =
MiGetPteAddress (
FIRST_MAPPING_PTE);
01732
MmLastReservedMappingPte =
MiGetPteAddress (
LAST_MAPPING_PTE);
01733
01734
MmWorkingSetList =
WORKING_SET_LIST;
01735
MmWsle = (
PMMWSLE)((PUCHAR)
WORKING_SET_LIST +
sizeof(
MMWSL));
01736
01737
01738
01739
01740
01741
01742
01743 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE((
PMMPTE)PDE_SELFMAP));
01744 Pfn1->
u2.ShareCount = 0;
01745 Pfn1->
u3.e2.ReferenceCount = 0;
01746
01747
01748
01749
01750
01751
01752
01753 PointerPte =
MiGetPpeAddress(
HYPER_SPACE);
01754 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE(PointerPte));
01755 Pfn1->
u2.ShareCount = 0;
01756 Pfn1->
u3.e2.ReferenceCount = 0;
01757
01758
01759
01760
01761
01762
01763
01764
01765 StartPde =
MiGetPdeAddress(
HYPER_SPACE);
01766
01767 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE(StartPde));
01768 Pfn1->
u2.ShareCount = 0;
01769 Pfn1->
u3.e2.ReferenceCount = 0;
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782 Pfn1 =
MI_PFN_ELEMENT (PdePageNumber);
01783 Pfn1->
u2.ShareCount = 0;
01784 Pfn1->
u3.e2.ReferenceCount = 0;
01785
01786 CurrentProcess =
PsGetCurrentProcess ();
01787
01788
01789
01790
01791
01792
01793 PageFrameIndex =
MiRemoveAnyPage (0);
01794
01795 CurrentProcess->
WorkingSetPage = PageFrameIndex;
01796 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
01797
01798 RtlZeroMemory (KSEG_ADDRESS(PageFrameIndex),
PAGE_SIZE);
01799
01800 CurrentProcess->
Vm.
MaximumWorkingSetSize = (ULONG)
MmSystemProcessWorkingSetMax;
01801 CurrentProcess->
Vm.
MinimumWorkingSetSize = (ULONG)
MmSystemProcessWorkingSetMin;
01802
01803
MmInitializeProcessAddressSpace (CurrentProcess,
01804 (
PEPROCESS)
NULL,
01805 (PVOID)
NULL,
01806 (PVOID)
NULL);
01807
01808
01809
01810
01811
01812
01813
01814
01815
KeFlushCurrentTb();
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
if ((((ULONG_PTR)
MmFreePagesByColor[0] & (
PAGE_SIZE - 1)) == 0) &&
01828 ((
MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES)) <
PAGE_SIZE)) {
01829
01830
PMMCOLOR_TABLES c;
01831
01832
c =
MmFreePagesByColor[0];
01833
01834
MmFreePagesByColor[0] =
ExAllocatePoolWithTag (
NonPagedPoolMustSucceed,
01835
MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES),
01836 ' mM');
01837
01838
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
01839
01840 RtlMoveMemory (
MmFreePagesByColor[0],
01841
c,
01842
MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES));
01843
01844
01845
01846
01847
01848
if (!
MI_IS_PHYSICAL_ADDRESS(
c)) {
01849 PointerPte =
MiGetPteAddress(
c);
01850 PageFrameIndex =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPte);
01851
MI_WRITE_INVALID_PTE(PointerPte,
ZeroKernelPte);
01852 }
else {
01853 PageFrameIndex =
MI_CONVERT_PHYSICAL_TO_PFN (
c);
01854 }
01855
01856 Pfn1 =
MI_PFN_ELEMENT (PageFrameIndex);
01857
ASSERT ((Pfn1->
u2.ShareCount <= 1) && (Pfn1->
u3.e2.ReferenceCount <= 1));
01858 Pfn1->
u2.ShareCount = 0;
01859 Pfn1->
u3.e2.ReferenceCount = 1;
01860
MI_SET_PFN_DELETED (Pfn1);
01861
#if DBG
01862
Pfn1->
u3.e1.PageLocation =
StandbyPageList;
01863
#endif //DBG
01864
MiDecrementReferenceCount (PageFrameIndex);
01865 }
01866
01867
return;
01868 }
01869
01870 PVOID
01871 MiGetKSegAddress (
01872 PFN_NUMBER FrameNumber
01873 )
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891 {
01892 PVOID
Virtual;
01893
PMMPTE PointerPte;
01894
MMPTE TempPte;
01895
01896
ASSERT (FrameNumber <=
MmHighestPhysicalPage);
01897
01898
Virtual = ((PVOID)(KSEG3_BASE | ((ULONG_PTR)(FrameNumber) <<
PAGE_SHIFT)));
01899
01900
#if defined(KSEG_VHPT)
01901
PointerPte =
MiGetKSegPteAddress (
Virtual);
01902
01903
if (PointerPte->
u.Long == 0) {
01904
01905
01906
01907
01908
01909 TempPte =
ValidKernelPte;
01910 TempPte.
u.Hard.PageFrameNumber = FrameNumber;
01911
MI_WRITE_VALID_PTE(PointerPte, TempPte);
01912
01913 __mf();
01914 }
01915
#endif
01916
01917
return (
Virtual);
01918 }
01919
01920
VOID
01921 MiConvertToSuperPages(
01922 IN PVOID StartVirtual,
01923 IN PVOID EndVirtual,
01924 IN SIZE_T PageSize,
01925 IN ULONG PageShift
01926 )
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951 {
01952 ULONG_PTR VirtualAddress;
01953 ULONG_PTR i;
01954 ULONG_PTR NumberOfPte;
01955
PMMPTE StartPte;
01956
01957 VirtualAddress = (ULONG_PTR)
PAGE_ALIGN(StartVirtual);
01958 i = VirtualAddress & (PageSize - 1);
01959
01960
if (i != 0) {
01961
01962 VirtualAddress = (VirtualAddress + PageSize - 1) & ~(PageSize - 1);
01963
01964 }
01965
01966 StartPte =
MiGetPteAddress(VirtualAddress);
01967 NumberOfPte = PageSize >>
PAGE_SHIFT;
01968
01969 i = 0;
01970
01971
while (VirtualAddress <= (ULONG_PTR)EndVirtual) {
01972
01973
if (i == NumberOfPte) {
01974
01975 StartPte -= NumberOfPte;
01976
01977
for (i = 0; i < NumberOfPte; i++) {
01978
01979 StartPte->
u.Hard.Valid = 0;
01980 StartPte->
u.Large.LargePage = 1;
01981 StartPte->
u.Large.PageSize = PageShift;
01982 StartPte += 1;
01983 }
01984
01985 i = 0;
01986 }
01987
01988 i += 1;
01989 StartPte += 1;
01990 VirtualAddress +=
PAGE_SIZE;
01991 }
01992 }
01993
01994
VOID
01995 MiConvertBackToStandardPages(
01996 IN PVOID StartVirtual,
01997 IN PVOID EndVirtual
01998 )
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017 {
02018 ULONG_PTR VirtualAddress;
02019 ULONG_PTR i;
02020 ULONG_PTR NumberOfPte;
02021
PMMPTE StartPte;
02022
MMPTE TempPte;
02023
02024 VirtualAddress = (ULONG_PTR)
PAGE_ALIGN(StartVirtual);
02025
02026 StartPte =
MiGetPteAddress(VirtualAddress);
02027
02028
while (VirtualAddress <= (ULONG_PTR)EndVirtual) {
02029
02030 TempPte = *StartPte;
02031 TempPte.
u.Large.PageSize = 0;
02032 TempPte.
u.Large.PageSize = 0;
02033 TempPte.
u.Hard.Valid = 1;
02034
MI_WRITE_VALID_PTE (StartPte, TempPte);
02035
02036 StartPte += 1;
02037 VirtualAddress +=
PAGE_SIZE;
02038 }
02039 }
02040
02041
VOID
02042 MiSweepCacheMachineDependent(
02043 IN PVOID VirtualAddress,
02044 IN SIZE_T Size,
02045 IN
MEMORY_CACHING_TYPE CacheType
02046 )
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066 {
02067 PFN_NUMBER j;
02068 PFN_NUMBER NumberOfPages;
02069 KIRQL OldIrql;
02070
PMMPTE PointerPte;
02071
MMPTE TempPte;
02072
02073 NumberOfPages =
COMPUTE_PAGES_SPANNED (VirtualAddress,
Size);
02074 VirtualAddress =
PAGE_ALIGN(VirtualAddress);
02075
Size = NumberOfPages *
PAGE_SIZE;
02076
02077
KeSweepCacheRangeWithDrain(
TRUE, VirtualAddress, (ULONG)
Size);
02078
02079
if (CacheType ==
MmWriteCombined) {
02080 PointerPte =
MiGetPteAddress(VirtualAddress);
02081
for (j = 0; j < NumberOfPages; j += 1) {
02082 TempPte = *PointerPte;
02083
MI_SET_PTE_WRITE_COMBINE (TempPte);
02084
MI_WRITE_VALID_PTE (PointerPte, TempPte);
02085 PointerPte += 1;
02086 }
02087 }
02088 }
02089
02090
VOID
02091 MiBuildPageTableForDrivers(
02092 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02093 )
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109 {
02110
PMMPTE StartPte;
02111
PMMPTE EndPte;
02112
PMMPTE StartPde;
02113
PMMPTE StartPpe;
02114
MMPTE TempPte;
02115 ULONG First;
02116 ULONG_PTR i;
02117 PLIST_ENTRY NextEntry;
02118 ULONG NumberOfLoaderPtes;
02119 PFN_NUMBER NextPhysicalPage;
02120 PVOID Va;
02121 PLDR_DATA_TABLE_ENTRY DataTableEntry;
02122
02123 TempPte =
ValidKernelPte;
02124 TempPte.
u.Long |=
MM_PTE_EXECUTE;
02125
02126 i = 0;
02127 NextEntry = LoaderBlock->LoadOrderListHead.Flink;
02128
02129
for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) {
02130
02131
02132
02133
02134
02135 i += 1;
02136
if (i <= 1) {
02137
continue;
02138 }
02139
02140 DataTableEntry = CONTAINING_RECORD(NextEntry,
02141 LDR_DATA_TABLE_ENTRY,
02142 InLoadOrderLinks);
02143
02144 NumberOfLoaderPtes = (ULONG)((
ROUND_TO_PAGES(DataTableEntry->SizeOfImage)) >>
PAGE_SHIFT);
02145
02146 Va = DataTableEntry->DllBase;
02147 StartPte =
MiGetPteAddress(Va);
02148 EndPte = StartPte + NumberOfLoaderPtes;
02149
02150 First =
TRUE;
02151
02152
while (StartPte <= EndPte) {
02153
02154
if (First ==
TRUE ||
MiIsPteOnPpeBoundary(StartPte)) {
02155 StartPpe =
MiGetPdeAddress(StartPte);
02156
if (StartPpe->
u.Hard.Valid == 0) {
02157
ASSERT (StartPpe->
u.Long == 0);
02158 NextPhysicalPage =
MiGetNextPhysicalPage();
02159 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
02160 TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
02161
MI_WRITE_VALID_PTE(StartPpe, TempPte);
02162 }
02163 }
02164
02165
if ((First ==
TRUE) ||
MiIsPteOnPdeBoundary(StartPte)) {
02166 First =
FALSE;
02167 StartPde =
MiGetPteAddress(StartPte);
02168
if (StartPde->
u.Hard.Valid == 0) {
02169 NextPhysicalPage =
MiGetNextPhysicalPage();
02170 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
02171 TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
02172
MI_WRITE_VALID_PTE(StartPde, TempPte);
02173 }
02174 }
02175
02176 TempPte.
u.Hard.PageFrameNumber =
MI_CONVERT_PHYSICAL_TO_PFN(Va);
02177
MI_WRITE_VALID_PTE (StartPte, TempPte);
02178 StartPte += 1;
02179 Va = (PVOID)((ULONG_PTR)Va +
PAGE_SIZE);
02180 }
02181 }
02182 }
02183
02184 PVOID
02185 MiConvertToLoaderVirtual(
02186 IN PFN_NUMBER Page,
02187 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02188 )
02189 {
02190 ULONG_PTR PageAddress = Page <<
PAGE_SHIFT;
02191 PTR_INFO ItrInfo = &LoaderBlock->u.Ia64.ItrInfo[0];
02192
02193
02194
if ((PageAddress >= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress) &&
02195 (PageAddress <= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress +
02196 ((ULONG_PTR)1 << ItrInfo[ITR_KERNEL_INDEX].PageSize))) {
02197
02198
return (PVOID)(ItrInfo[ITR_KERNEL_INDEX].VirtualAddress +
02199 (PageAddress - ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress));
02200
02201 }
else if ((PageAddress >= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress) &&
02202 (PageAddress <= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress +
02203 ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER0_INDEX].PageSize))) {
02204
02205
return (PVOID)(ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress +
02206 (PageAddress - ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress));
02207
02208 }
else if ((PageAddress >= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress) &&
02209 (PageAddress <= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress +
02210 ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER1_INDEX].PageSize))) {
02211
02212
return (PVOID)(ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress +
02213 (PageAddress - ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress));
02214
02215 }
else {
02216
02217
KeBugCheckEx (MEMORY_MANAGEMENT,
02218 0x01010101,
02219 PageAddress,
02220 (ULONG_PTR)&ItrInfo[0],
02221 (ULONG_PTR)LoaderBlock);
02222
02223
return 0;
02224 }
02225 }
02226
02227
02228
VOID
02229 MiBuildPageTableForLoaderMemory(
02230 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02231 )
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 {
02249
PMMPTE StartPte;
02250
PMMPTE EndPte;
02251
PMMPTE StartPde;
02252
PMMPTE StartPpe;
02253
MMPTE TempPte;
02254 ULONG First;
02255 PLIST_ENTRY NextEntry;
02256 PFN_NUMBER NextPhysicalPage;
02257 PVOID Va;
02258 PFN_NUMBER PfnNumber;
02259
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
02260
02261 TempPte =
ValidKernelPte;
02262 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
02263
02264
for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
02265
02266 MemoryDescriptor = CONTAINING_RECORD(NextEntry,
02267
MEMORY_ALLOCATION_DESCRIPTOR,
02268 ListEntry);
02269
02270
if ((MemoryDescriptor->
MemoryType ==
LoaderOsloaderHeap) ||
02271 (MemoryDescriptor->
MemoryType ==
LoaderRegistryData) ||
02272 (MemoryDescriptor->
MemoryType ==
LoaderNlsData) ||
02273 (MemoryDescriptor->
MemoryType ==
LoaderStartupDpcStack) ||
02274 (MemoryDescriptor->
MemoryType ==
LoaderStartupKernelStack) ||
02275 (MemoryDescriptor->
MemoryType ==
LoaderStartupPanicStack) ||
02276 (MemoryDescriptor->
MemoryType ==
LoaderStartupPdrPage) ||
02277 (MemoryDescriptor->
MemoryType ==
LoaderMemoryData)) {
02278
02279 TempPte.
u.Hard.Execute = 0;
02280
02281 }
else if ((MemoryDescriptor->
MemoryType ==
LoaderSystemCode) ||
02282 (MemoryDescriptor->
MemoryType ==
LoaderHalCode) ||
02283 (MemoryDescriptor->
MemoryType ==
LoaderBootDriver) ||
02284 (MemoryDescriptor->
MemoryType ==
LoaderStartupDpcStack)) {
02285
02286 TempPte.
u.Hard.Execute = 1;
02287
02288 }
else {
02289
02290
continue;
02291
02292 }
02293
02294 PfnNumber = MemoryDescriptor->
BasePage;
02295 Va =
MiConvertToLoaderVirtual(MemoryDescriptor->
BasePage, LoaderBlock);
02296
02297 StartPte =
MiGetPteAddress(Va);
02298 EndPte = StartPte + MemoryDescriptor->
PageCount;
02299
02300 First =
TRUE;
02301
02302
while (StartPte <= EndPte) {
02303
02304
if (First ==
TRUE ||
MiIsPteOnPpeBoundary(StartPte)) {
02305 StartPpe =
MiGetPdeAddress(StartPte);
02306
if (StartPpe->
u.Hard.Valid == 0) {
02307
ASSERT (StartPpe->
u.Long == 0);
02308 NextPhysicalPage =
MiGetNextPhysicalPage();
02309 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
02310 TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
02311
MI_WRITE_VALID_PTE(StartPpe, TempPte);
02312 }
02313 }
02314
02315
if ((First ==
TRUE) ||
MiIsPteOnPdeBoundary(StartPte)) {
02316 First =
FALSE;
02317 StartPde =
MiGetPteAddress(StartPte);
02318
if (StartPde->
u.Hard.Valid == 0) {
02319 NextPhysicalPage =
MiGetNextPhysicalPage();
02320 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage),
PAGE_SIZE);
02321 TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
02322
MI_WRITE_VALID_PTE(StartPde, TempPte);
02323 }
02324 }
02325
02326 TempPte.
u.Hard.PageFrameNumber = PfnNumber;
02327
MI_WRITE_VALID_PTE (StartPte, TempPte);
02328 StartPte += 1;
02329 PfnNumber += 1;
02330 Va = (PVOID)((ULONG_PTR)Va +
PAGE_SIZE);
02331 }
02332 }
02333 }
02334
02335
02336
VOID
02337 MiRemoveLoaderSuperPages(
02338 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02339 )
02340 {
02341
02342
02343
02344
02345
02346 KiFlushFixedInstTb(
FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress);
02347 KiFlushFixedInstTb(
FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress);
02348 KiFlushFixedDataTb(
FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER0_INDEX].VirtualAddress);
02349 KiFlushFixedDataTb(
FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER1_INDEX].VirtualAddress);
02350
02351 }
02352
02353
VOID
02354 MiMakeKernelPagesPermanent(
02355 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02356 )
02357 {
02358 PFN_NUMBER KernelStart;
02359 PFN_NUMBER KernelEnd;
02360 ULONG_PTR PageSize;
02361 PLIST_ENTRY NextEntry;
02362
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
02363
02364 KernelStart =
MiNtoskrnlPhysicalBase >>
PAGE_SHIFT;
02365 PageSize = (ULONG_PTR)1 <<
MiNtoskrnlPageShift;
02366 KernelEnd = KernelStart + (PageSize >>
PAGE_SHIFT);
02367
02368 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
02369
02370
for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
02371
02372 MemoryDescriptor = CONTAINING_RECORD(NextEntry,
02373
MEMORY_ALLOCATION_DESCRIPTOR,
02374 ListEntry);
02375
02376
if (((MemoryDescriptor->
BasePage >= KernelStart) &&
02377 (MemoryDescriptor->
BasePage < KernelEnd)) &&
02378 ((MemoryDescriptor->
MemoryType ==
LoaderOsloaderHeap) ||
02379 (MemoryDescriptor->
MemoryType ==
LoaderRegistryData) ||
02380 (MemoryDescriptor->
MemoryType ==
LoaderNlsData))) {
02381
02382
02383
02384
02385
02386 MemoryDescriptor->
MemoryType =
LoaderSpecialMemory;
02387
02388 }
02389
02390 }
02391 }
02392
02393
VOID
02394 MiCheckMemoryDescriptorList(
02395 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02396 )
02397 {
02398 PFN_NUMBER KernelStart;
02399 PFN_NUMBER KernelEnd;
02400 ULONG_PTR PageSize;
02401 PLIST_ENTRY NextEntry;
02402 PLIST_ENTRY PreviousEntry;
02403
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
02404
PMEMORY_ALLOCATION_DESCRIPTOR PreviousMemoryDescriptor;
02405
02406
02407 KernelStart =
MiNtoskrnlPhysicalBase >>
PAGE_SHIFT;
02408 PageSize = (ULONG_PTR)1 <<
MiNtoskrnlPageShift;
02409 KernelEnd = KernelStart + (PageSize >>
PAGE_SHIFT);
02410
02411 PreviousMemoryDescriptor =
NULL;
02412 PreviousEntry =
NULL;
02413
02414 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
02415
02416
for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
02417
02418 MemoryDescriptor = CONTAINING_RECORD(NextEntry,
02419
MEMORY_ALLOCATION_DESCRIPTOR,
02420 ListEntry);
02421
02422
#if DBG
02423
if (
MiPrintMemoryDescriptors) {
02424
DbgPrint(
"MemoryType = %x\n", MemoryDescriptor->
MemoryType);
02425
DbgPrint(
"BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->
BasePage <<
PAGE_SHIFT);
02426
DbgPrint(
"PageCount = %x\n\n", MemoryDescriptor->
PageCount <<
PAGE_SHIFT);
02427 }
02428
#endif
02429
if ((MemoryDescriptor->
BasePage >= KernelStart) &&
02430 (MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount <= KernelEnd)) {
02431
02432
if (MemoryDescriptor->
MemoryType ==
LoaderSystemBlock) {
02433
02434 MemoryDescriptor->
MemoryType =
LoaderFirmwareTemporary;
02435
02436 }
else if (MemoryDescriptor->
MemoryType ==
LoaderSpecialMemory) {
02437
02438 MemoryDescriptor->
MemoryType =
LoaderFirmwareTemporary;
02439
02440 }
02441 }
02442
02443
02444
if ((PreviousMemoryDescriptor !=
NULL) &&
02445 (MemoryDescriptor->
MemoryType == PreviousMemoryDescriptor->
MemoryType) &&
02446 (MemoryDescriptor->
BasePage ==
02447 (PreviousMemoryDescriptor->
BasePage + PreviousMemoryDescriptor->
PageCount))) {
02448
02449 PreviousMemoryDescriptor->
PageCount += MemoryDescriptor->
PageCount;
02450 PreviousEntry->Flink = NextEntry->Flink;
02451
02452 }
else {
02453
02454 PreviousMemoryDescriptor = MemoryDescriptor;
02455 PreviousEntry = NextEntry;
02456
02457 }
02458
02459 }
02460
02461 }