ReactOS 0.4.15-dev-8236-g99f0937
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:113
#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:355
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:171
#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 355 of file wlmemory.c.

357{
358 PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
359 PLIST_ENTRY PreviousEntry, NextEntry;
360 PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
361
362 TRACE("BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
363 NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]);
364
365 /* Find a place where to insert the new descriptor to */
366 PreviousEntry = ListHead;
367 NextEntry = ListHead->Flink;
368 while (NextEntry != ListHead)
369 {
370 NextDescriptor = CONTAINING_RECORD(NextEntry,
372 ListEntry);
373 if (NewDescriptor->BasePage < NextDescriptor->BasePage)
374 break;
375
376 PreviousEntry = NextEntry;
377 PreviousDescriptor = NextDescriptor;
378 NextEntry = NextEntry->Flink;
379 }
380
381 /* Don't forget about merging free areas */
382 if (NewDescriptor->MemoryType != LoaderFree)
383 {
384 /* Just insert, nothing to merge */
385 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
386 }
387 else
388 {
389 /* Previous block also free? */
390 if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType == LoaderFree) &&
391 ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
392 NewDescriptor->BasePage))
393 {
394 /* Just enlarge previous descriptor's PageCount */
395 PreviousDescriptor->PageCount += NewDescriptor->PageCount;
396 NewDescriptor = PreviousDescriptor;
397 }
398 else
399 {
400 /* Nope, just insert */
401 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
402 }
403
404 /* Next block is free ?*/
405 if ((NextEntry != ListHead) &&
406 (NextDescriptor->MemoryType == LoaderFree) &&
407 ((NewDescriptor->BasePage + NewDescriptor->PageCount) == NextDescriptor->BasePage))
408 {
409 /* Enlarge next descriptor's PageCount */
410 NewDescriptor->PageCount += NextDescriptor->PageCount;
411 RemoveEntryList(&NextDescriptor->ListEntry);
412 }
413 }
414
415 return;
416}
#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;
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
233 // Always map first page of memory
235 if (!Status)
236 {
237 ERR("Error during MempSetupPaging of first page\n");
238 return FALSE;
239 }
240
241 /* Before creating the map, we need to map pages to kernel mode */
242 LastPageIndex = 1;
243 LastPageType = MemoryMap[1].PageAllocated;
244 for (i = 2; i < NoEntries; i++)
245 {
246 if ((MemoryMap[i].PageAllocated != LastPageType) ||
247 (i == NoEntries - 1))
248 {
249 MempSetupPagingForRegion(LastPageIndex, i - LastPageIndex, LastPageType);
250 LastPageIndex = i;
251 LastPageType = MemoryMap[i].PageAllocated;
252 }
253 }
254
255 // Construct a good memory map from what we've got,
256 // but mark entries which the memory allocation bitmap takes
257 // as free entries (this is done in order to have the ability
258 // to place mem alloc bitmap outside lower 16Mb zone)
259 PagesCount = 1;
260 LastPageIndex = 0;
261 LastPageType = MemoryMap[0].PageAllocated;
262 for (i = 1; i < NoEntries; i++)
263 {
264 // Check if its memory map itself
265 if (i >= MemoryMapStartPage &&
266 i < (MemoryMapStartPage+MemoryMapSizeInPages))
267 {
268 // Exclude it if current page belongs to the memory map
269 MemoryMap[i].PageAllocated = LoaderFree;
270 }
271
272 // Process entry
273 if (MemoryMap[i].PageAllocated == LastPageType &&
274 (i != NoEntries-1) )
275 {
276 PagesCount++;
277 }
278 else
279 {
280 // Add the resulting region
281 MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
282
283 // Reset our counter vars
284 LastPageIndex = i;
285 LastPageType = MemoryMap[i].PageAllocated;
286 PagesCount = 1;
287 }
288 }
289
290 // TEMP, DEBUG!
291 // adding special reserved memory zones for vmware workstation
292#if 0
293 {
294 Mad[MadCount].BasePage = 0xfec00;
295 Mad[MadCount].PageCount = 0x10;
297 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
298 MadCount++;
299
300 Mad[MadCount].BasePage = 0xfee00;
301 Mad[MadCount].PageCount = 0x1;
303 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
304 MadCount++;
305
306 Mad[MadCount].BasePage = 0xfffe0;
307 Mad[MadCount].PageCount = 0x20;
309 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
310 MadCount++;
311 }
312#endif
313
314 /* Now we need to add high descriptors from the bios memory map */
315 for (i = 0; i < BiosMemoryMapEntryCount; i++)
316 {
317 /* Check if its higher than the lookup table */
319 {
320 /* Copy this descriptor */
321 MempAddMemoryBlock(LoaderBlock,
325 }
326 }
327
328 TRACE("MadCount: %d\n", MadCount);
329
330 WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
331
332 // Map our loader image, so we can continue running
333 /*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >> MM_PAGE_SHIFT);
334 if (!Status)
335 {
336 UiMessageBox("Error during MempSetupPaging.");
337 return;
338 }*/
339
340 // Fill the memory descriptor list and
341 //PrepareMemoryDescriptorList();
342 TRACE("Memory Descriptor List prepared, printing PDE\n");
343 List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
344
345#if DBG
346 MempDump();
347#endif
348
349 return TRUE;
350}
VOID MempDump(VOID)
Definition: winldr.c:431
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:249
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#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 WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1285
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.