00117 :
00118
00119 This routine performs
the necessary operations to enable
virtual
00120 memory. This includes building
the page directory parent pages and
00121
the page directories
for the system, building page table pages to map
00122
the code section,
the data section,
the stack section and
the trap handler.
00123 It also initializes
the PFN database and populates
the free list.
00124
00125 Arguments:
00126
00127 LoaderBlock - Supplies
the address of
the loader block.
00128
00129 Return Value:
00130
00131 None.
00132
00133 Environment:
00134
00135 Kernel mode.
00136
00137 --*/
00138
00139 {
00140 LOGICAL First;
00141
CHAR Buffer[256];
00142
PMMPFN BasePfn;
00143
PMMPFN BottomPfn;
00144
PMMPFN TopPfn;
00145 PFN_NUMBER i;
00146 ULONG j;
00147 PFN_NUMBER HighPage;
00148 PFN_NUMBER PagesLeft;
00149 PFN_NUMBER PageNumber;
00150 PFN_NUMBER PtePage;
00151 PFN_NUMBER PdePage;
00152 PFN_NUMBER PpePage;
00153 PFN_NUMBER FrameNumber;
00154 PFN_NUMBER PfnAllocation;
00155
PEPROCESS CurrentProcess;
00156 PVOID SpinLockPage;
00157 PFN_NUMBER MostFreePage;
00158 PFN_NUMBER MostFreeLowMem;
00159 PLIST_ENTRY NextMd;
00160 SIZE_T MaxPool;
00161 PFN_NUMBER NextPhysicalPage;
00162 KIRQL OldIrql;
00163
PMEMORY_ALLOCATION_DESCRIPTOR FreeDescriptorLowMem;
00164
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
00165
MMPTE TempPte;
00166
PMMPTE PointerPde;
00167
PMMPTE PointerPte;
00168
PMMPTE LastPte;
00169
PMMPTE CacheStackPage;
00170
PMMPTE Pde;
00171
PMMPTE StartPpe;
00172
PMMPTE StartPde;
00173
PMMPTE StartPte;
00174
PMMPTE EndPpe;
00175
PMMPTE EndPde;
00176
PMMPTE EndPte;
00177
PMMPFN Pfn1;
00178
PMMPFN Pfn2;
00179 PULONG PointerLong;
00180
PMMFREE_POOL_ENTRY Entry;
00181 PVOID NonPagedPoolStartVirtual;
00182 ULONG Range;
00183
00184 MostFreePage = 0;
00185 MostFreeLowMem = 0;
00186 FreeDescriptorLowMem =
NULL;
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
MmHiberPages = 96;
00205
00206 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00207
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00208 MemoryDescriptor = CONTAINING_RECORD(NextMd,
00209
MEMORY_ALLOCATION_DESCRIPTOR,
00210 ListEntry);
00211
00212 HighPage = MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount - 1;
00213
00214
00215
00216
00217
00218
if (MemoryDescriptor->
MemoryType !=
LoaderBad) {
00219
MmNumberOfPhysicalPages += (PFN_COUNT)MemoryDescriptor->
PageCount;
00220 }
00221
00222
00223
00224
00225
00226
00227
if (MemoryDescriptor->
BasePage <
MmLowestPhysicalPage) {
00228
MmLowestPhysicalPage = MemoryDescriptor->
BasePage;
00229 }
00230
00231
00232
00233
00234
00235
00236
if (HighPage >
MmHighestPhysicalPage) {
00237
MmHighestPhysicalPage = HighPage;
00238 }
00239
00240
00241
00242
00243
00244
00245
if ((MemoryDescriptor->
MemoryType ==
LoaderFree) ||
00246 (MemoryDescriptor->
MemoryType ==
LoaderLoadedProgram) ||
00247 (MemoryDescriptor->
MemoryType ==
LoaderFirmwareTemporary) ||
00248 (MemoryDescriptor->
MemoryType ==
LoaderOsloaderStack)) {
00249
00250
00251
00252
00253
00254
00255
00256
if (MemoryDescriptor->
MemoryType !=
LoaderFree) {
00257
MmHiberPages += MemoryDescriptor->
PageCount;
00258 }
00259
00260
if ((MemoryDescriptor->
PageCount > MostFreeLowMem) &&
00261 (MemoryDescriptor->
BasePage <
_4gbInPages) &&
00262 (HighPage <
_4gbInPages)) {
00263 MostFreeLowMem = MemoryDescriptor->
PageCount;
00264 FreeDescriptorLowMem = MemoryDescriptor;
00265
00266 }
else if (MemoryDescriptor->
PageCount > MostFreePage) {
00267 MostFreePage = MemoryDescriptor->
PageCount;
00268
MxFreeDescriptor = MemoryDescriptor;
00269 }
00270 }
else if (MemoryDescriptor->
MemoryType ==
LoaderOsloaderHeap) {
00271
00272
00273
00274
00275
00276
MmHiberPages += MemoryDescriptor->
PageCount;
00277 }
00278
00279 NextMd = MemoryDescriptor->
ListEntry.Flink;
00280 }
00281
00282
MmHighestPossiblePhysicalPage =
MmHighestPhysicalPage;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
if (
MmNumberOfPhysicalPages < 1024) {
00293
KeBugCheckEx(INSTALL_MORE_MEMORY,
00294 MmNumberOfPhysicalPages,
00295 MmLowestPhysicalPage,
00296 MmHighestPhysicalPage,
00297 0);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
if (FreeDescriptorLowMem ==
NULL) {
00307
InbvDisplayString(
"MmInit *** FATAL ERROR *** no free memory below 4gb\n");
00308
KeBugCheck(MEMORY_MANAGEMENT);
00309 }
00310
00311
00312
00313
00314
00315
MxNextPhysicalPage = FreeDescriptorLowMem->
BasePage;
00316
MxNumberOfPages = FreeDescriptorLowMem->
PageCount;
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
if ((
MmSizeOfNonPagedPoolInBytes >>
PAGE_SHIFT) >
00329 (7 * (
MmNumberOfPhysicalPages >> 3))) {
00330
MmSizeOfNonPagedPoolInBytes = 0;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
if (
MmSizeOfNonPagedPoolInBytes <
MmMinimumNonPagedPoolSize) {
00340
MmSizeOfNonPagedPoolInBytes =
MmMinimumNonPagedPoolSize;
00341
if (
MmNumberOfPhysicalPages > 1024) {
00342
MmSizeOfNonPagedPoolInBytes +=
00343 ((
MmNumberOfPhysicalPages - 1024) /
_1mbInPages) *
00344
MmMinAdditionNonPagedPoolPerMb;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
MmSizeOfNonPagedPoolInBytes &= ~(
PAGE_SIZE - 1);
00353
00354
00355
00356
00357
00358
if (
MmSizeOfNonPagedPoolInBytes >
MM_MAX_INITIAL_NONPAGED_POOL) {
00359
MmSizeOfNonPagedPoolInBytes =
MM_MAX_INITIAL_NONPAGED_POOL;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
if ((
MmSizeOfNonPagedPoolInBytes >>
PAGE_SHIFT) >
MxNumberOfPages) {
00371
00372
00373
00374
00375
00376
MmSizeOfNonPagedPoolInBytes =
MxNumberOfPages <<
PAGE_SHIFT;
00377
if(
MmSizeOfNonPagedPoolInBytes <
MmMinimumNonPagedPoolSize) {
00378
InbvDisplayString(
"MmInit *** FATAL ERROR *** cannot allocate nonpaged pool\n");
00379
sprintf(Buffer,
00380
"Largest description = %d pages, require %d pages\n",
00381 MxNumberOfPages,
00382 MmMinimumNonPagedPoolSize >> PAGE_SHIFT);
00383
00384
InbvDisplayString(Buffer);
00385
KeBugCheck(MEMORY_MANAGEMENT);
00386 }
00387 }
00388
00389
00390
00391
00392
00393
00394
MxNextPhysicalPage += (PFN_NUMBER)(
MmSizeOfNonPagedPoolInBytes >>
PAGE_SHIFT);
00395
MxNumberOfPages -= (PFN_NUMBER)(
MmSizeOfNonPagedPoolInBytes >>
PAGE_SHIFT);
00396
00397
00398
00399
00400
00401
if (
MmMaximumNonPagedPoolInBytes == 0) {
00402
00403
00404
00405
00406
00407
00408
MmMaximumNonPagedPoolInBytes =
MmDefaultMaximumNonPagedPool;
00409
00410
00411
00412
00413
00414
MmMaximumNonPagedPoolInBytes +=
00415 ((ULONG_PTR)
PAGE_ALIGN((MmHighestPhysicalPage + 1) *
sizeof(
MMPFN)));
00416
00417
00418
00419
00420
00421
00422
if (
MmNumberOfPhysicalPages > 1024) {
00423
MmMaximumNonPagedPoolInBytes +=
00424 ((
MmNumberOfPhysicalPages - 1024) /
_1mbInPages) *
00425
MmMaxAdditionNonPagedPoolPerMb;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
if (
MmMaximumNonPagedPoolInBytes >
MM_MAX_DEFAULT_NONPAGED_POOL) {
00435
MmMaximumNonPagedPoolInBytes =
MM_MAX_DEFAULT_NONPAGED_POOL;
00436 }
00437 }
00438
00439
00440
00441
00442
00443
MmMaximumNonPagedPoolInBytes &= ~(
PAGE_SIZE - 1);
00444
00445
00446
00447
00448
00449
00450 MaxPool =
MmSizeOfNonPagedPoolInBytes + (
PAGE_SIZE * 16) +
00451 ((ULONG_PTR)
PAGE_ALIGN((MmHighestPhysicalPage + 1) *
sizeof(
MMPFN)));
00452
00453
00454
00455
00456
00457
00458
00459
if (
MmMaximumNonPagedPoolInBytes < MaxPool) {
00460
MmMaximumNonPagedPoolInBytes = MaxPool;
00461 }
00462
00463
00464
00465
00466
00467
if (
MmMaximumNonPagedPoolInBytes >
MM_MAX_ADDITIONAL_NONPAGED_POOL) {
00468
MmMaximumNonPagedPoolInBytes =
MM_MAX_ADDITIONAL_NONPAGED_POOL;
00469 }
00470
00471
00472
00473
00474
00475
MmNonPagedPoolStart = (PCHAR)
MmNonPagedPoolEnd -
MmMaximumNonPagedPoolInBytes;
00476 NonPagedPoolStartVirtual =
MmNonPagedPoolStart;
00477
00478
00479
00480
00481
00482
00483
MmNonPagedSystemStart = (PVOID)(((ULONG_PTR)
MmNonPagedPoolStart -
00484 (((ULONG_PTR)
MmNumberOfSystemPtes + 1) *
PAGE_SIZE)) &
00485 (~
PAGE_DIRECTORY2_MASK));
00486
00487
00488
00489
00490
00491
00492
if (
MmNonPagedSystemStart <
MM_LOWEST_NONPAGED_SYSTEM_START) {
00493
MmNonPagedSystemStart =
MM_LOWEST_NONPAGED_SYSTEM_START;
00494 }
00495
00496
00497
00498
00499
00500
MmNumberOfSystemPtes = (ULONG)(((ULONG_PTR)
MmNonPagedPoolStart -
00501 (ULONG_PTR)
MmNonPagedSystemStart) >>
PAGE_SHIFT) - 1;
00502
00503
ASSERT(MmNumberOfSystemPtes > 1000);
00504
00505
00506
00507
00508
00509 StartPde =
MiGetPdeAddress(MM_SYSTEM_SPACE_START);
00510 EndPde =
MiGetPdeAddress(MM_SYSTEM_SPACE_END);
00511 First =
TRUE;
00512
00513
while (StartPde <= EndPde) {
00514
00515
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00516 First =
FALSE;
00517 StartPpe =
MiGetPteAddress(StartPde);
00518
if (StartPpe->
u.Hard.Valid == 0) {
00519 StartPpe += 1;
00520 StartPde =
MiGetVirtualAddressMappedByPte (StartPpe);
00521
continue;
00522 }
00523 TempPte = *StartPpe;
00524 TempPte.
u.Hard.Global = 1;
00525 *StartPpe = TempPte;
00526 }
00527
00528 TempPte = *StartPde;
00529 TempPte.
u.Hard.Global = 1;
00530 *StartPde = TempPte;
00531 StartPde += 1;
00532 }
00533
00534
00535
00536
00537
00538
if (
MiHydra ==
TRUE) {
00539
00540 StartPde =
MiGetPdeAddress(MmSessionBase);
00541 EndPde =
MiGetPdeAddress(MI_SESSION_SPACE_END);
00542 First =
TRUE;
00543
00544
while (StartPde < EndPde) {
00545
00546
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00547 First =
FALSE;
00548 StartPpe =
MiGetPteAddress(StartPde);
00549
if (StartPpe->
u.Hard.Valid == 0) {
00550 StartPpe += 1;
00551 StartPde =
MiGetVirtualAddressMappedByPte (StartPpe);
00552
continue;
00553 }
00554 TempPte = *StartPpe;
00555 TempPte.
u.Hard.Global = 0;
00556 *StartPpe = TempPte;
00557 }
00558
00559 TempPte = *StartPde;
00560 TempPte.
u.Hard.Global = 0;
00561 *StartPde = TempPte;
00562
00563
ASSERT(StartPde->u.Long == 0);
00564
00565 StartPde += 1;
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 TempPte =
ValidKernelPte;
00585 TempPte.
u.Hard.Global = 0;
00586
00587 StartPde =
MiGetPdeAddress(HYPER_SPACE);
00588 StartPpe =
MiGetPteAddress(StartPde);
00589
00590
if (StartPpe->
u.Hard.Valid == 0) {
00591
ASSERT (StartPpe->
u.Long == 0);
00592 TempPte.
u.Hard.PageFrameNumber =
MxGetNextPage();
00593 *StartPpe = TempPte;
00594 RtlZeroMemory (MiGetVirtualAddressMappedByPte (StartPpe),
00595 PAGE_SIZE);
00596 }
00597
00598 TempPte.u.Hard.PageFrameNumber =
MxGetNextPage();
00599 *StartPde = TempPte;
00600
00601
00602
00603
00604
00605 StartPte =
MiGetPteAddress(HYPER_SPACE);
00606 RtlZeroMemory(StartPte, PAGE_SIZE);
00607
00608
00609
00610
00611
00612
00613 TempPte =
ValidKernelPte;
00614 StartPde =
MiGetPdeAddress(MmNonPagedSystemStart);
00615 EndPde =
MiGetPdeAddress(MmNonPagedPoolEnd);
00616 First =
TRUE;
00617
00618
while (StartPde <= EndPde) {
00619
00620
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00621 First =
FALSE;
00622 StartPpe =
MiGetPteAddress(StartPde);
00623
if (StartPpe->
u.Hard.Valid == 0) {
00624 TempPte.u.Hard.PageFrameNumber =
MxGetNextPage();
00625 *StartPpe = TempPte;
00626 RtlZeroMemory (MiGetVirtualAddressMappedByPte (StartPpe),
00627 PAGE_SIZE);
00628 }
00629 }
00630
00631
if (StartPde->
u.Hard.Valid == 0) {
00632 TempPte.u.Hard.PageFrameNumber =
MxGetNextPage();
00633 *StartPde = TempPte;
00634 }
00635 StartPde += 1;
00636 }
00637
00638
00639
00640
00641
00642 StartPte =
MiGetPteAddress(MmNonPagedSystemStart);
00643 EndPte =
MiGetPteAddress(MmNonPagedPoolEnd);
00644
00645
if (!
MiIsPteOnPdeBoundary (EndPte)) {
00646 EndPte = (
PMMPTE)((ULONG_PTR)
PAGE_ALIGN (EndPte) +
PAGE_SIZE);
00647 }
00648
00649 RtlZeroMemory(StartPte, (ULONG_PTR)EndPte - (ULONG_PTR)StartPte);
00650
00651
00652
00653
00654
00655
00656
00657
00658 StartPte =
MiGetPteAddress(MmNonPagedPoolStart);
00659 EndPte =
MiGetPteAddress((PCHAR)MmNonPagedPoolStart +
00660 MmSizeOfNonPagedPoolInBytes);
00661
00662 PageNumber = FreeDescriptorLowMem->
BasePage;
00663
00664
#if 0
00665
ASSERT (MxFreeDescriptor == FreeDescriptorLowMem);
00666
MxNumberOfPages -= (EndPte - StartPte);
00667
MxNextPhysicalPage += (EndPte - StartPte);
00668
#endif
00669
00670
while (StartPte < EndPte) {
00671 TempPte.u.Hard.PageFrameNumber = PageNumber;
00672 PageNumber += 1;
00673 *StartPte = TempPte;
00674 StartPte += 1;
00675 }
00676
00677
00678
00679
00680
00681
00682
while (!
MiIsPteOnPdeBoundary (StartPte)) {
00683 *StartPte =
ZeroKernelPte;
00684 StartPte += 1;
00685 }
00686
00687
00688
00689
00690
00691
00692 PointerPte =
MiGetPteAddress(MmNonPagedPoolStart);
00693
MmNonPagedPoolStart = KSEG_ADDRESS(PointerPte->
u.Hard.PageFrameNumber);
00694
MmPageAlignedPoolBase[
NonPagedPool] =
MmNonPagedPoolStart;
00695
00696
00697
00698
00699
00700
00701
MmSubsectionBase = 0;
00702
MmSubsectionTopPage = (
KSEG2_BASE -
KSEG0_BASE) >>
PAGE_SHIFT;
00703
00704
00705
00706
00707
00708
MmNonPagedPoolExpansionStart =
00709 (PCHAR)NonPagedPoolStartVirtual +
MmSizeOfNonPagedPoolInBytes;
00710
00711
MiInitializeNonPagedPool ();
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
if (
MmSecondaryColors == 0) {
00727
MmSecondaryColors = PCR->SecondLevelCacheSize;
00728 }
00729
00730
MmSecondaryColors =
MmSecondaryColors >>
PAGE_SHIFT;
00731
00732
00733
00734
00735
00736
if (((
MmSecondaryColors & (
MmSecondaryColors - 1)) != 0) ||
00737 (
MmSecondaryColors <
MM_SECONDARY_COLORS_MIN) ||
00738 (
MmSecondaryColors >
MM_SECONDARY_COLORS_MAX)) {
00739
MmSecondaryColors =
MM_SECONDARY_COLORS_DEFAULT;
00740 }
00741
00742
MmSecondaryColorMask =
MmSecondaryColors - 1;
00743 PfnAllocation =
00744 1 + ((((
MmHighestPhysicalPage + 1) *
sizeof(
MMPFN)) +
00745 ((PFN_NUMBER)
MmSecondaryColors *
sizeof(
MMCOLOR_TABLES) * 2)) >>
PAGE_SHIFT);
00746
00747
00748
00749
00750
00751
00752
00753
00754
#ifndef PFN_CONSISTENCY
00755
00756
if (
MxNumberOfPages >= PfnAllocation) {
00757
00758
00759
00760
00761
00762
00763
00764
00765 HighPage =
MxNextPhysicalPage +
MxNumberOfPages;
00766
MmPfnDatabase = KSEG_ADDRESS(HighPage - PfnAllocation);
00767 RtlZeroMemory(MmPfnDatabase, PfnAllocation * PAGE_SIZE);
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
MxNumberOfPages -= PfnAllocation;
00781
if ((
MxNextPhysicalPage >= FreeDescriptorLowMem->
BasePage) &&
00782 (
MxNextPhysicalPage < (FreeDescriptorLowMem->
BasePage +
00783 FreeDescriptorLowMem->
PageCount))) {
00784 FreeDescriptorLowMem->
PageCount -= (PFN_COUNT)PfnAllocation;
00785
00786 }
else {
00787
MxFreeDescriptor->
PageCount -= (PFN_COUNT)PfnAllocation;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
MiReserveSystemPtes(1, NonPagedPoolExpansion, 0, 0, TRUE);
00800
00801 }
else {
00802
00803
#endif // PFN_CONSISTENCY
00804
00805
00806
00807
00808
00809
00810 PointerPte =
MiReserveSystemPtes((ULONG)PfnAllocation,
00811 NonPagedPoolExpansion,
00812 0,
00813 0,
00814 TRUE);
00815
00816
#if PFN_CONSISTENCY
00817
00818 MiPfnStartPte = PointerPte;
00819 MiPfnPtes = PfnAllocation;
00820
00821
#endif
00822
00823
MmPfnDatabase = (
PMMPFN)(
MiGetVirtualAddressMappedByPte(PointerPte));
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
MiReserveSystemPtes(1, NonPagedPoolExpansion, 0, 0, TRUE);
00836
00837
00838
00839
00840
00841
00842
00843
00844 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00845
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00846 MemoryDescriptor = CONTAINING_RECORD(NextMd,
00847
MEMORY_ALLOCATION_DESCRIPTOR,
00848 ListEntry);
00849
00850 PointerPte =
MiGetPteAddress(
MI_PFN_ELEMENT(
00851 MemoryDescriptor->
BasePage));
00852
00853 HighPage = MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount;
00854 LastPte =
MiGetPteAddress((PCHAR)
MI_PFN_ELEMENT(HighPage) - 1);
00855
while (PointerPte <= LastPte) {
00856
if (PointerPte->u.Hard.Valid == 0) {
00857 TempPte.u.Hard.PageFrameNumber =
MxGetNextPage();
00858 *PointerPte = TempPte;
00859 RtlZeroMemory(
MiGetVirtualAddressMappedByPte(PointerPte),
00860 PAGE_SIZE);
00861 }
00862
00863 PointerPte += 1;
00864 }
00865
00866 NextMd = MemoryDescriptor->
ListEntry.Flink;
00867 }
00868
00869
#ifndef PFN_CONSISTENCY
00870
00871 }
00872
00873
#endif // PFN_CONSISTENCY
00874
00875
00876
00877
00878
00879
MmFreePagesByColor[0] =
00880 (
PMMCOLOR_TABLES)&
MmPfnDatabase[
MmHighestPhysicalPage + 1];
00881
00882
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
00883
00884
00885
00886
00887
00888
00889
if (
MI_IS_PHYSICAL_ADDRESS(MmFreePagesByColor[0]) ==
FALSE) {
00890 PointerPte =
MiGetPteAddress(&MmFreePagesByColor[0][0]);
00891 LastPte =
00892
MiGetPteAddress((PCHAR)&MmFreePagesByColor[1][MmSecondaryColors] - 1);
00893
00894
while (PointerPte <= LastPte) {
00895
if (PointerPte->u.Hard.Valid == 0) {
00896 TempPte.u.Hard.PageFrameNumber =
MxGetNextPage();
00897 *PointerPte = TempPte;
00898 RtlZeroMemory(
MiGetVirtualAddressMappedByPte(PointerPte),
00899 PAGE_SIZE);
00900 }
00901
00902 PointerPte += 1;
00903 }
00904 }
00905
00906
00907
00908
00909
00910
for (i = 0; i <
MmSecondaryColors; i += 1) {
00911
MmFreePagesByColor[
ZeroedPageList][i].
Flink =
MM_EMPTY_LIST;
00912
MmFreePagesByColor[
FreePageList][i].
Flink =
MM_EMPTY_LIST;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922 PointerPde = (
PMMPTE)PDE_SELFMAP;
00923 PpePage =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPde);
00924 Pfn1 =
MI_PFN_ELEMENT(PpePage);
00925 Pfn1->
PteFrame = PpePage;
00926 Pfn1->
PteAddress = PointerPde;
00927 Pfn1->
u2.ShareCount += 1;
00928 Pfn1->
u3.e2.ReferenceCount = 1;
00929 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
00930 Pfn1->
u3.e1.PageColor =
00931
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(PointerPde));
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 StartPde =
MiGetPdeAddress(HYPER_SPACE);
00944 EndPde =
MiGetPdeAddress(NON_PAGED_SYSTEM_END);
00945 First =
TRUE;
00946
00947
while (StartPde <= EndPde) {
00948
00949
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
00950 First =
FALSE;
00951 StartPpe =
MiGetPteAddress(StartPde);
00952
if (StartPpe->
u.Hard.Valid == 0) {
00953 StartPpe += 1;
00954 StartPde =
MiGetVirtualAddressMappedByPte (StartPpe);
00955
continue;
00956 }
00957
00958 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPpe);
00959
00960 Pfn1 =
MI_PFN_ELEMENT(PdePage);
00961 Pfn1->
PteFrame = PpePage;
00962 Pfn1->
PteAddress = StartPde;
00963 Pfn1->
u2.ShareCount += 1;
00964 Pfn1->
u3.e2.ReferenceCount = 1;
00965 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
00966 Pfn1->
u3.e1.PageColor =
00967
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe));
00968 }
00969
00970
00971
00972
00973
00974
00975
if (StartPde->
u.Hard.Valid == 1) {
00976
00977 PtePage =
MI_GET_PAGE_FRAME_FROM_PTE(StartPde);
00978 Pfn1 =
MI_PFN_ELEMENT(PtePage);
00979 Pfn1->
PteFrame = PdePage;
00980 Pfn1->
PteAddress = StartPde;
00981 Pfn1->
u2.ShareCount += 1;
00982 Pfn1->
u3.e2.ReferenceCount = 1;
00983 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
00984 Pfn1->
u3.e1.PageColor =
00985
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPde));
00986
00987
00988
00989
00990
00991 PointerPte =
MiGetVirtualAddressMappedByPte(StartPde);
00992
00993
if ((PointerPte <
MiGetPteAddress (KSEG0_BASE)) ||
00994 (PointerPte >=
MiGetPteAddress (KSEG2_BASE))) {
00995
00996
for (j = 0 ; j <
PTE_PER_PAGE; j += 1) {
00997
00998
00999
01000
01001
01002
01003
if (PointerPte->u.Hard.Valid == 1) {
01004 FrameNumber =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPte);
01005 Pfn2 =
MI_PFN_ELEMENT(FrameNumber);
01006 Pfn2->
PteFrame = PtePage;
01007 Pfn2->
PteAddress = (
PMMPTE)KSEG_ADDRESS(PtePage) + j;
01008 Pfn2->
u2.ShareCount += 1;
01009 Pfn2->
u3.e2.ReferenceCount = 1;
01010 Pfn2->
u3.e1.PageLocation =
ActiveAndValid;
01011 Pfn2->
u3.e1.PageColor =
01012
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(Pfn2->
PteAddress));
01013 }
01014
01015 PointerPte += 1;
01016 }
01017 }
01018 }
01019
01020 StartPde += 1;
01021 }
01022
01023
01024
01025
01026
01027
01028
01029 Pfn1 = &
MmPfnDatabase[
MmLowestPhysicalPage];
01030
if (Pfn1->
u3.e2.ReferenceCount == 0) {
01031 Pde =
MiGetPdeAddress(0xFFFFFFFFB0000000);
01032 PdePage =
MI_GET_PAGE_FRAME_FROM_PTE(Pde);
01033 Pfn1->
PteFrame = PdePage;
01034 Pfn1->
PteAddress = Pde;
01035 Pfn1->
u2.ShareCount += 1;
01036 Pfn1->
u3.e2.ReferenceCount = 1;
01037 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01038 Pfn1->
u3.e1.PageColor =
01039
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(Pde));
01040 }
01041
01042
01043
01044
01045
01046
01047 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01048
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01049 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01050
MEMORY_ALLOCATION_DESCRIPTOR,
01051 ListEntry);
01052
01053
01054
01055
01056
01057
01058 i = MemoryDescriptor->
PageCount;
01059 NextPhysicalPage = MemoryDescriptor->
BasePage;
01060
switch (MemoryDescriptor->
MemoryType) {
01061
01062
01063
01064
01065
01066
01067
case LoaderBad:
01068
while (i != 0) {
01069
MiInsertPageInList(MmPageLocationList[BadPageList],
01070 NextPhysicalPage);
01071
01072 i -= 1;
01073 NextPhysicalPage += 1;
01074 }
01075
01076
break;
01077
01078
01079
01080
01081
01082
01083
case LoaderFree:
01084
case LoaderLoadedProgram:
01085
case LoaderFirmwareTemporary:
01086
case LoaderOsloaderStack:
01087 Pfn1 =
MI_PFN_ELEMENT(NextPhysicalPage);
01088
while (i != 0) {
01089
01090
01091
01092
01093
01094
01095
01096
if (Pfn1->
u3.e2.ReferenceCount == 0) {
01097 Pfn1->
PteAddress = KSEG_ADDRESS(NextPhysicalPage);
01098 Pfn1->
u3.e1.PageColor =
01099
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(Pfn1->
PteAddress));
01100
01101
MiInsertPageInList(MmPageLocationList[FreePageList],
01102 NextPhysicalPage);
01103 }
01104
01105 Pfn1 += 1;
01106 i -= 1;
01107 NextPhysicalPage += 1;
01108 }
01109
01110
break;
01111
01112
01113
01114
01115
01116
01117
default:
01118 PointerPte = KSEG_ADDRESS(NextPhysicalPage);
01119 Pfn1 =
MI_PFN_ELEMENT(NextPhysicalPage);
01120
while (i != 0) {
01121
01122
01123
01124
01125
01126 Pfn1->
PteFrame = PpePage;
01127 Pfn1->
PteAddress = PointerPte;
01128 Pfn1->
u2.ShareCount += 1;
01129 Pfn1->
u3.e2.ReferenceCount = 1;
01130 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01131 Pfn1->
u3.e1.PageColor =
01132
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(PointerPte));
01133
01134 Pfn1 += 1;
01135 i -= 1;
01136 NextPhysicalPage += 1;
01137 PointerPte += 1;
01138 }
01139
01140
break;
01141 }
01142
01143 NextMd = MemoryDescriptor->
ListEntry.Flink;
01144 }
01145
01146
01147
01148
01149
01150
if (
MI_IS_PHYSICAL_ADDRESS(MmPfnDatabase) ==
FALSE) {
01151
01152
01153
01154
01155
01156
01157
01158 Pfn1 =
MI_PFN_ELEMENT(
MiGetPteAddress(&MmPfnDatabase[MmLowestPhysicalPage])->u.Hard.PageFrameNumber);
01159 Pfn1->
u3.e1.StartOfAllocation = 1;
01160 Pfn1 =
MI_PFN_ELEMENT(
MiGetPteAddress(&MmPfnDatabase[MmHighestPhysicalPage])->u.Hard.PageFrameNumber);
01161 Pfn1->
u3.e1.EndOfAllocation = 1;
01162
01163 }
else {
01164
01165
01166
01167
01168
01169
01170
01171 PageNumber =
MI_CONVERT_PHYSICAL_TO_PFN(MmPfnDatabase);
01172 Pfn1 =
MI_PFN_ELEMENT(PageNumber);
01173
do {
01174 Pfn1->
PteAddress = KSEG_ADDRESS(PageNumber);
01175 Pfn1->
u3.e1.PageColor =
01176
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(Pfn1->
PteAddress));
01177
01178 Pfn1->
u3.e2.ReferenceCount += 1;
01179 PageNumber += 1;
01180 Pfn1 += 1;
01181 PfnAllocation -= 1;
01182 }
while (PfnAllocation != 0);
01183
01184
01185
01186
01187
01188
01189 BottomPfn =
MI_PFN_ELEMENT(MmHighestPhysicalPage);
01190
do {
01191
01192
01193
01194
01195
01196
01197
01198
if (((ULONG_PTR)BottomPfn & (
PAGE_SIZE - 1)) != 0) {
01199 BasePfn = (
PMMPFN)((ULONG_PTR)BottomPfn & ~(
PAGE_SIZE - 1));
01200 TopPfn = BottomPfn + 1;
01201
01202 }
else {
01203 BasePfn = (
PMMPFN)((ULONG_PTR)BottomPfn -
PAGE_SIZE);
01204 TopPfn = BottomPfn;
01205 }
01206
01207
while (BottomPfn > BasePfn) {
01208 BottomPfn -= 1;
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218 Range = (ULONG)((ULONG_PTR)TopPfn - (ULONG_PTR)BottomPfn);
01219
if (
RtlCompareMemoryUlong((PVOID)BottomPfn, Range, 0) == Range) {
01220
01221
01222
01223
01224
01225
01226 PageNumber = (PFN_NUMBER)(((ULONG_PTR)BasePfn - KSEG43_BASE) >>
PAGE_SHIFT);
01227 Pfn1 =
MI_PFN_ELEMENT(PageNumber);
01228
01229
ASSERT(Pfn1->
u3.e2.ReferenceCount == 1);
01230
01231 Pfn1->
u3.e2.ReferenceCount = 0;
01232 PfnAllocation += 1;
01233 Pfn1->
PteAddress = KSEG_ADDRESS(PageNumber);
01234 Pfn1->
u3.e1.PageColor =
01235
MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(Pfn1->
PteAddress));
01236
01237
MiInsertPageInList(MmPageLocationList[FreePageList],
01238 PageNumber);
01239 }
01240
01241 }
while (BottomPfn >
MmPfnDatabase);
01242 }
01243
01244
01245
01246
01247
01248 i =
MmSizeOfNonPagedMustSucceed;
01249 Pfn1 =
MI_PFN_ELEMENT(
MI_CONVERT_PHYSICAL_TO_PFN(MmNonPagedMustSucceed));
01250
while (i != 0) {
01251 Pfn1->
u3.e1.StartOfAllocation = 1;
01252 Pfn1->
u3.e1.EndOfAllocation = 1;
01253 i -=
PAGE_SIZE;
01254 Pfn1 += 1;
01255 }
01256
01257
01258
01259
01260
01261
01262
01263
01264 PointerPte =
MiGetPteAddress(MmNonPagedSystemStart);
01265
MmNumberOfSystemPtes = (ULONG)(
MiGetPteAddress(MmNonPagedPoolExpansionStart) - PointerPte - 1);
01266
KeInitializeSpinLock(&MmSystemSpaceLock);
01267
KeInitializeSpinLock(&MmPfnLock);
01268
MiInitializeSystemPtes(PointerPte, MmNumberOfSystemPtes, SystemPteSpace);
01269
01270
01271
01272
01273
01274
InitializePool(NonPagedPool, 0);
01275
01276
01277
01278
01279
01280
01281
01282
MmFirstReservedMappingPte =
MiGetPteAddress(FIRST_MAPPING_PTE);
01283
MmLastReservedMappingPte =
MiGetPteAddress(LAST_MAPPING_PTE);
01284
01285
01286
01287
01288
01289
MmWorkingSetList =
WORKING_SET_LIST;
01290
MmWsle = (
PMMWSLE)((PUCHAR)
WORKING_SET_LIST +
sizeof(
MMWSL));
01291
01292
01293
01294
01295
01296
01297
01298 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE((
PMMPTE)PDE_SELFMAP));
01299 Pfn1->
u2.ShareCount = 0;
01300 Pfn1->
u3.e2.ReferenceCount = 0;
01301
01302
01303
01304
01305
01306
01307
01308 PointerPte =
MiGetPpeAddress(HYPER_SPACE);
01309 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE(PointerPte));
01310 Pfn1->
u2.ShareCount = 0;
01311 Pfn1->
u3.e2.ReferenceCount = 0;
01312
01313
01314
01315
01316
01317
01318
01319
01320 StartPde =
MiGetPdeAddress(HYPER_SPACE);
01321
01322 Pfn1 =
MI_PFN_ELEMENT(
MI_GET_PAGE_FRAME_FROM_PTE(StartPde));
01323 Pfn1->
u2.ShareCount = 0;
01324 Pfn1->
u3.e2.ReferenceCount = 0;
01325
01326
01327
01328
01329
01330
01331
01332
LOCK_PFN(OldIrql);
01333
01334 FrameNumber =
MiRemoveZeroPageIfAny (0);
01335
if (FrameNumber == 0) {
01336 FrameNumber =
MiRemoveAnyPage (0);
01337
UNLOCK_PFN (OldIrql);
01338
MiZeroPhysicalPage (FrameNumber, 0);
01339
LOCK_PFN (OldIrql);
01340
01341 Pfn1 =
MI_PFN_ELEMENT(FrameNumber);
01342 Pfn1->
u2.ShareCount = 0;
01343 Pfn1->
u3.e2.ReferenceCount = 0;
01344 }
01345
01346 CurrentProcess =
PsGetCurrentProcess();
01347 CurrentProcess->
WorkingSetPage = FrameNumber;
01348 PointerPte =
MiGetVirtualAddressMappedByPte(EndPde);
01349
01350
UNLOCK_PFN(OldIrql);
01351
01352
01353
01354
01355
01356
01357 PointerPte =
MmFirstReservedMappingPte;
01358 PointerPte->
u.Hard.PageFrameNumber =
NUMBER_OF_MAPPING_PTES;
01359 CurrentProcess->
Vm.
MaximumWorkingSetSize = (ULONG)
MmSystemProcessWorkingSetMax;
01360 CurrentProcess->
Vm.
MinimumWorkingSetSize = (ULONG)
MmSystemProcessWorkingSetMin;
01361
01362
MmInitializeProcessAddressSpace(CurrentProcess, NULL, NULL, NULL);
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
if ((((ULONG_PTR)
MmFreePagesByColor[0] & (
PAGE_SIZE - 1)) == 0) &&
01375 ((
MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES)) <
PAGE_SIZE)) {
01376
01377
PMMCOLOR_TABLES c;
01378
01379
c =
MmFreePagesByColor[0];
01380
MmFreePagesByColor[0] =
01381
ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
01382 MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES),
01383 ' mM');
01384
01385
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
01386
01387 RtlMoveMemory (MmFreePagesByColor[0],
01388 c,
01389 MmSecondaryColors * 2 *
sizeof(
MMCOLOR_TABLES));
01390
01391
01392
01393
01394
01395
if (!
MI_IS_PHYSICAL_ADDRESS(c)) {
01396 PointerPte =
MiGetPteAddress(c);
01397 FrameNumber =
MI_GET_PAGE_FRAME_FROM_PTE(PointerPte);
01398 *PointerPte =
ZeroKernelPte;
01399
01400 }
else {
01401 FrameNumber =
MI_CONVERT_PHYSICAL_TO_PFN(c);
01402 }
01403
01404
LOCK_PFN (OldIrql);
01405
01406 Pfn1 =
MI_PFN_ELEMENT (FrameNumber);
01407
01408
ASSERT ((Pfn1->
u3.e2.ReferenceCount <= 1) && (Pfn1->
u2.ShareCount <= 1));
01409
01410 Pfn1->
u2.ShareCount = 0;
01411 Pfn1->
u3.e2.ReferenceCount = 0;
01412
MI_SET_PFN_DELETED(Pfn1);
01413
01414
#if DBG
01415
01416 Pfn1->
u3.e1.PageLocation =
StandbyPageList;
01417
01418
#endif //DBG
01419
01420
MiInsertPageInList (MmPageLocationList[FreePageList], FrameNumber);
01421
01422
UNLOCK_PFN (OldIrql);
01423 }
01424
01425
return;
01426 }
}