ReactOS 0.4.15-dev-6679-g945ee4b
wlmemory.c File Reference
#include <freeldr.h>
#include "winldr.h"
#include <debug.h>
Include dependency graph for wlmemory.c:

Go to the source code of this file.

Macros

#define MAX_MAD_COUNT   200
 

Functions

 DBG_DEFAULT_CHANNEL (WINDOWS)
 
static VOID WinLdrInsertDescriptor (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
 
VOID MempAddMemoryBlock (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
 
VOID MempSetupPagingForRegion (PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
 
BOOLEAN WinLdrSetupMemoryLayout (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
 

Variables

ULONG LoaderPagesSpanned
 
static const PCSTR MemTypeDesc []
 
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
 
ULONG BiosMemoryMapEntryCount
 
PFN_NUMBER MmLowestPhysicalPage
 
PFN_NUMBER MmHighestPhysicalPage
 
MEMORY_ALLOCATION_DESCRIPTORMad
 
ULONG MadCount = 0
 

Macro Definition Documentation

◆ MAX_MAD_COUNT

#define MAX_MAD_COUNT   200

Definition at line 60 of file wlmemory.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WINDOWS  )

◆ MempAddMemoryBlock()

VOID MempAddMemoryBlock ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock,
PFN_NUMBER  BasePage,
PFN_NUMBER  PageCount,
ULONG  Type 
)

Definition at line 65 of file wlmemory.c.

69{
70 TRACE("MempAddMemoryBlock(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
71 BasePage, PageCount, Type);
72
73 /* Check for memory block after 4GB - we don't support it yet
74 Note: Even last page before 4GB limit is not supported */
75 if (BasePage >= MM_MAX_PAGE)
76 {
77 /* Just skip this, without even adding to MAD list */
78 return;
79 }
80
81 /* Check if last page is after 4GB limit and shorten this block if needed */
82 if (BasePage + PageCount > MM_MAX_PAGE)
83 {
84 /* Shorten this block */
85 PageCount = MM_MAX_PAGE - BasePage;
86 }
87
88 /* Check if we have slots left */
90 {
91 ERR("Error: no MAD slots left!\n");
92 return;
93 }
94
95 /* Set Base page, page count and type */
96 Mad[MadCount].BasePage = BasePage;
97 Mad[MadCount].PageCount = PageCount;
99
100 /* Add descriptor */
101 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
102 MadCount++;
103}
Type
Definition: Type.h:7
#define ERR(fmt,...)
Definition: debug.h:110
#define TRACE(s)
Definition: solgame.cpp:4
TYPE_OF_MEMORY MemoryType
Definition: arc.h:240
#define MAX_MAD_COUNT
Definition: wlmemory.c:60
MEMORY_ALLOCATION_DESCRIPTOR * Mad
Definition: wlmemory.c:57
static VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
Definition: wlmemory.c:356
ULONG MadCount
Definition: wlmemory.c:58

Referenced by WinLdrSetupMemoryLayout().

◆ MempSetupPagingForRegion()

VOID MempSetupPagingForRegion ( PFN_NUMBER  BasePage,
PFN_NUMBER  PageCount,
ULONG  Type 
)

Definition at line 106 of file wlmemory.c.

110{
112
113 TRACE("MempSetupPagingForRegion(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
114 BasePage, PageCount, Type);
115
116 /* Make sure we don't map too high */
117 if (BasePage + PageCount > LoaderPagesSpanned) return;
118
119 switch (Type)
120 {
121 /* Pages used by the loader */
125 /* Map these pages into user mode */
126 Status = MempSetupPaging(BasePage, PageCount, FALSE);
127 break;
128
129 /* Pages used by the kernel */
133 case LoaderSystemCode:
134 case LoaderHalCode:
135 case LoaderBootDriver:
144 case LoaderMemoryData:
145 case LoaderNlsData:
146 case LoaderXIPRom:
147 case LoaderOsloaderHeap: // FIXME
148 /* Map these pages into kernel mode */
149 Status = MempSetupPaging(BasePage, PageCount, TRUE);
150 break;
151
152 /* Pages not in use */
153 case LoaderFree:
154 case LoaderBad:
155 break;
156
157 /* Invisible to kernel */
160 case LoaderBBTMemory:
161 break;
162
163 // FIXME: not known (not used anyway)
164 case LoaderReserve:
167 break;
168 }
169
170 if (!Status)
171 {
172 ERR("Error during MempSetupPaging\n");
173 }
174}
unsigned char BOOLEAN
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:170
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:25
@ LoaderBad
Definition: arc.h:177
@ LoaderMemoryData
Definition: arc.h:194
@ LoaderReserve
Definition: arc.h:198
@ LoaderBootDriver
Definition: arc.h:185
@ LoaderOsloaderHeap
Definition: arc.h:181
@ LoaderFree
Definition: arc.h:176
@ LoaderConsoleInDriver
Definition: arc.h:186
@ LoaderFirmwareTemporary
Definition: arc.h:179
@ LoaderLoadedProgram
Definition: arc.h:178
@ LoaderSystemCode
Definition: arc.h:183
@ LoaderNlsData
Definition: arc.h:195
@ LoaderLargePageFiller
Definition: arc.h:201
@ LoaderStartupDpcStack
Definition: arc.h:188
@ LoaderHALCachedMemory
Definition: arc.h:200
@ LoaderRegistryData
Definition: arc.h:193
@ LoaderHalCode
Definition: arc.h:184
@ LoaderFirmwarePermanent
Definition: arc.h:180
@ LoaderErrorLogMemory
Definition: arc.h:202
@ LoaderStartupPcrPage
Definition: arc.h:191
@ LoaderOsloaderStack
Definition: arc.h:182
@ LoaderSpecialMemory
Definition: arc.h:196
@ LoaderSystemBlock
Definition: arc.h:175
@ LoaderStartupPdrPage
Definition: arc.h:192
@ LoaderExceptionBlock
Definition: arc.h:174
@ LoaderXIPRom
Definition: arc.h:199
@ LoaderStartupKernelStack
Definition: arc.h:189
@ LoaderStartupPanicStack
Definition: arc.h:190
@ LoaderConsoleOutDriver
Definition: arc.h:187
@ LoaderBBTMemory
Definition: arc.h:197
ULONG LoaderPagesSpanned
Definition: mm.c:29

Referenced by WinLdrSetupMemoryLayout().

◆ WinLdrInsertDescriptor()

static VOID WinLdrInsertDescriptor ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PMEMORY_ALLOCATION_DESCRIPTOR  NewDescriptor 
)
static

Definition at line 356 of file wlmemory.c.

358{
359 PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
360 PLIST_ENTRY PreviousEntry, NextEntry;
361 PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
362
363 TRACE("BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
364 NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]);
365
366 /* Find a place where to insert the new descriptor to */
367 PreviousEntry = ListHead;
368 NextEntry = ListHead->Flink;
369 while (NextEntry != ListHead)
370 {
371 NextDescriptor = CONTAINING_RECORD(NextEntry,
373 ListEntry);
374 if (NewDescriptor->BasePage < NextDescriptor->BasePage)
375 break;
376
377 PreviousEntry = NextEntry;
378 PreviousDescriptor = NextDescriptor;
379 NextEntry = NextEntry->Flink;
380 }
381
382 /* Don't forget about merging free areas */
383 if (NewDescriptor->MemoryType != LoaderFree)
384 {
385 /* Just insert, nothing to merge */
386 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
387 }
388 else
389 {
390 /* Previous block also free? */
391 if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType == LoaderFree) &&
392 ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
393 NewDescriptor->BasePage))
394 {
395 /* Just enlarge previous descriptor's PageCount */
396 PreviousDescriptor->PageCount += NewDescriptor->PageCount;
397 NewDescriptor = PreviousDescriptor;
398 }
399 else
400 {
401 /* Nope, just insert */
402 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
403 }
404
405 /* Next block is free ?*/
406 if ((NextEntry != ListHead) &&
407 (NextDescriptor->MemoryType == LoaderFree) &&
408 ((NewDescriptor->BasePage + NewDescriptor->PageCount) == NextDescriptor->BasePage))
409 {
410 /* Enlarge next descriptor's PageCount */
411 NewDescriptor->PageCount += NextDescriptor->PageCount;
412 RemoveEntryList(&NextDescriptor->ListEntry);
413 }
414 }
415
416 return;
417}
#define NULL
Definition: types.h:112
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static const PCSTR MemTypeDesc[]
Definition: wlmemory.c:19
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:30

Referenced by MempAddMemoryBlock(), and WinLdrSetupMemoryLayout().

◆ WinLdrSetupMemoryLayout()

BOOLEAN WinLdrSetupMemoryLayout ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 181 of file wlmemory.c.

182{
183 PFN_NUMBER i, PagesCount, MemoryMapSizeInPages, NoEntries;
184 PFN_NUMBER LastPageIndex, MemoryMapStartPage;
186 ULONG LastPageType;
187 //PKTSS Tss;
188 //BOOLEAN Status;
189
190 /* Cleanup heap */
192
193 //
194 // Creating a suitable memory map for Windows can be tricky, so let's
195 // give a few advices:
196 // 1) One must not map the whole available memory pages to PDE!
197 // Map only what's needed - 16Mb, 24Mb, 32Mb max I think,
198 // thus occupying 4, 6 or 8 PDE entries for identical mapping,
199 // the same quantity for KSEG0_BASE mapping, one more entry for
200 // hyperspace and one more entry for HAL physical pages mapping.
201 // 2) Memory descriptors must map *the whole* physical memory
202 // showing any memory above 16/24/32 as FirmwareTemporary
203 //
204 // 3) Overall memory blocks count must not exceed 30 (?? why?)
205 //
206
207 //
208 // During MmInitMachineDependent, the kernel zeroes PDE at the following address
209 // 0xC0300000 - 0xC03007FC
210 //
211 // Then it finds the best place for non-paged pool:
212 // StartPde C0300F70, EndPde C0300FF8, NumberOfPages C13, NextPhysPage 3AD
213 //
214
215 // Allocate memory for memory allocation descriptors
218
219 // Setup an entry for each descriptor
220 MemoryMap = MmGetMemoryMap(&NoEntries);
221 if (MemoryMap == NULL)
222 {
223 UiMessageBox("Can not retrieve the current memory map.");
224 return FALSE;
225 }
226
227 // Calculate parameters of the memory map
228 MemoryMapStartPage = (ULONG_PTR)MemoryMap >> MM_PAGE_SHIFT;
229 MemoryMapSizeInPages = (NoEntries * sizeof(PAGE_LOOKUP_TABLE_ITEM) + MM_PAGE_SIZE - 1) / MM_PAGE_SIZE;
230
231 TRACE("Got memory map with %d entries\n", NoEntries);
232#if 0
233 // Always contiguously map low 1Mb of memory
234 Status = MempSetupPaging(0, 0x100, FALSE);
235 if (!Status)
236 {
237 ERR("Error during MempSetupPaging of low 1Mb\n");
238 return FALSE;
239 }
240#endif
241
242 /* Before creating the map, we need to map pages to kernel mode */
243 LastPageIndex = 1;
244 LastPageType = MemoryMap[1].PageAllocated;
245 for (i = 2; i < NoEntries; i++)
246 {
247 if ((MemoryMap[i].PageAllocated != LastPageType) ||
248 (i == NoEntries - 1))
249 {
250 MempSetupPagingForRegion(LastPageIndex, i - LastPageIndex, LastPageType);
251 LastPageIndex = i;
252 LastPageType = MemoryMap[i].PageAllocated;
253 }
254 }
255
256 // Construct a good memory map from what we've got,
257 // but mark entries which the memory allocation bitmap takes
258 // as free entries (this is done in order to have the ability
259 // to place mem alloc bitmap outside lower 16Mb zone)
260 PagesCount = 1;
261 LastPageIndex = 0;
262 LastPageType = MemoryMap[0].PageAllocated;
263 for (i = 1; i < NoEntries; i++)
264 {
265 // Check if its memory map itself
266 if (i >= MemoryMapStartPage &&
267 i < (MemoryMapStartPage+MemoryMapSizeInPages))
268 {
269 // Exclude it if current page belongs to the memory map
270 MemoryMap[i].PageAllocated = LoaderFree;
271 }
272
273 // Process entry
274 if (MemoryMap[i].PageAllocated == LastPageType &&
275 (i != NoEntries-1) )
276 {
277 PagesCount++;
278 }
279 else
280 {
281 // Add the resulting region
282 MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
283
284 // Reset our counter vars
285 LastPageIndex = i;
286 LastPageType = MemoryMap[i].PageAllocated;
287 PagesCount = 1;
288 }
289 }
290
291 // TEMP, DEBUG!
292 // adding special reserved memory zones for vmware workstation
293#if 0
294 {
295 Mad[MadCount].BasePage = 0xfec00;
296 Mad[MadCount].PageCount = 0x10;
298 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
299 MadCount++;
300
301 Mad[MadCount].BasePage = 0xfee00;
302 Mad[MadCount].PageCount = 0x1;
304 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
305 MadCount++;
306
307 Mad[MadCount].BasePage = 0xfffe0;
308 Mad[MadCount].PageCount = 0x20;
310 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
311 MadCount++;
312 }
313#endif
314
315 /* Now we need to add high descriptors from the bios memory map */
316 for (i = 0; i < BiosMemoryMapEntryCount; i++)
317 {
318 /* Check if its higher than the lookup table */
320 {
321 /* Copy this descriptor */
322 MempAddMemoryBlock(LoaderBlock,
326 }
327 }
328
329 TRACE("MadCount: %d\n", MadCount);
330
331 WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
332
333 // Map our loader image, so we can continue running
334 /*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >> MM_PAGE_SHIFT);
335 if (!Status)
336 {
337 UiMessageBox("Error during MempSetupPaging.");
338 return;
339 }*/
340
341 // Fill the memory descriptor list and
342 //PrepareMemoryDescriptorList();
343 TRACE("Memory Descriptor List prepared, printing PDE\n");
344 List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
345
346#if DBG
347 MempDump();
348#endif
349
350 return TRUE;
351}
VOID MempDump(VOID)
Definition: winldr.c:429
BIOS_MEMORY_MAP MemoryMap[32]
Definition: loader.c:11
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries)
Definition: mm.c:297
VOID FrLdrHeapCleanupAll(VOID)
Definition: heap.c:248
#define ULONG_PTR
Definition: config.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry)
ULONG PFN_NUMBER
Definition: ke.h:9
TYPE_OF_MEMORY MemoryType
Definition: mm.h:43
PFN_NUMBER PageCount
Definition: mm.h:45
PFN_NUMBER BasePage
Definition: mm.h:44
uint32_t ULONG
Definition: typedefs.h:59
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:357
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1266
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
Definition: meminit.c:33
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
VOID MempSetupPagingForRegion(PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:106
VOID MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:65
ULONG BiosMemoryMapEntryCount
Definition: meminit.c:34

Referenced by LoadAndBootWindowsCommon().

Variable Documentation

◆ BiosMemoryMap

PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
extern

◆ BiosMemoryMapEntryCount

ULONG BiosMemoryMapEntryCount
extern

Definition at line 34 of file meminit.c.

Referenced by MmInitializeMemoryManager(), and WinLdrSetupMemoryLayout().

◆ LoaderPagesSpanned

◆ Mad

Definition at line 57 of file wlmemory.c.

Referenced by MempAddMemoryBlock(), and WinLdrSetupMemoryLayout().

◆ MadCount

ULONG MadCount = 0

Definition at line 58 of file wlmemory.c.

Referenced by MempAddMemoryBlock(), and WinLdrSetupMemoryLayout().

◆ MemTypeDesc

const PCSTR MemTypeDesc[]
static
Initial value:
= {
"ExceptionBlock ",
"SystemBlock ",
"Free ",
"Bad ",
"LoadedProgram ",
"FirmwareTemporary ",
"FirmwarePermanent ",
"OsloaderHeap ",
"OsloaderStack ",
"SystemCode ",
"HalCode ",
"BootDriver ",
"ConsoleInDriver ",
"ConsoleOutDriver ",
"StartupDpcStack ",
"StartupKernelStack",
"StartupPanicStack ",
"StartupPcrPage ",
"StartupPdrPage ",
"RegistryData ",
"MemoryData ",
"NlsData ",
"SpecialMemory ",
"BBTMemory "
}

Definition at line 19 of file wlmemory.c.

Referenced by WinLdrInsertDescriptor().

◆ MmHighestPhysicalPage

PFN_NUMBER MmHighestPhysicalPage
extern

Definition at line 31 of file meminit.c.

Referenced by WinLdrSetupMemoryLayout().

◆ MmLowestPhysicalPage

PFN_NUMBER MmLowestPhysicalPage
extern

Definition at line 30 of file meminit.c.