00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "mi.h"
00028
#include <inbv.h>
00029
00030
00031
00032
00033
00034 #define _1mbInPages (0x100000 >> PAGE_SHIFT)
00035 #define _4gbInPages (0x100000000 >> PAGE_SHIFT)
00036
00037
00038
00039
00040
00041 PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
00042 PFN_NUMBER
MxNextPhysicalPage;
00043 PFN_NUMBER
MxNumberOfPages;
00044
00045 PFN_NUMBER
00046 MxGetNextPage (
00047 VOID
00048 )
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 {
00074
00075
00076
00077
00078
00079
00080
00081
if (
MxNumberOfPages != 0) {
00082
MxNumberOfPages -= 1;
00083
return MxNextPhysicalPage++;
00084
00085 }
else {
00086
00087
00088
00089
00090
00091
00092
if (
MxNextPhysicalPage ==
00093 (
MxFreeDescriptor->
BasePage +
MxFreeDescriptor->
PageCount)) {
00094
KeBugCheckEx(INSTALL_MORE_MEMORY,
00095
MmNumberOfPhysicalPages,
00096
MmLowestPhysicalPage,
00097
MmHighestPhysicalPage,
00098 0);
00099
00100
return 0;
00101
00102 }
else {
00103
MxNumberOfPages =
MxFreeDescriptor->
PageCount - 1;
00104
MxNextPhysicalPage =
MxFreeDescriptor->
BasePage;
00105
return MxNextPhysicalPage++;
00106 }
00107 }
00108 }
00109
00110
VOID
00111 MiInitMachineDependent (
00112 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00113 )
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
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 }