ReactOS 0.4.16-dev-1067-ge98bba2
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

static const PCSTR MemTypeDesc []
 
MEMORY_ALLOCATION_DESCRIPTORMad
 
ULONG MadCount = 0
 

Macro Definition Documentation

◆ MAX_MAD_COUNT

#define MAX_MAD_COUNT   200

Definition at line 53 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 58 of file wlmemory.c.

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

Referenced by WinLdrSetupMemoryLayout().

◆ MempSetupPagingForRegion()

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

Definition at line 99 of file wlmemory.c.

103{
105
106 TRACE("MempSetupPagingForRegion(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
107 BasePage, PageCount, Type);
108
109 /* Make sure we don't map too high */
110 if (BasePage + PageCount > MmGetLoaderPagesSpanned()) return;
111
112 switch (Type)
113 {
114 /* Pages used by the loader */
118 /* Map these pages into user mode */
119 Status = MempSetupPaging(BasePage, PageCount, FALSE);
120 break;
121
122 /* Pages used by the kernel */
126 case LoaderSystemCode:
127 case LoaderHalCode:
128 case LoaderBootDriver:
137 case LoaderMemoryData:
138 case LoaderNlsData:
139 case LoaderXIPRom:
140 case LoaderOsloaderHeap: // FIXME
141 /* Map these pages into kernel mode */
142 Status = MempSetupPaging(BasePage, PageCount, TRUE);
143 break;
144
145 /* Pages not in use */
146 case LoaderFree:
147 case LoaderBad:
148 break;
149
150 /* Invisible to kernel */
153 case LoaderBBTMemory:
154 break;
155
156 // FIXME: not known (not used anyway)
157 case LoaderReserve:
160 break;
161 }
162
163 if (!Status)
164 {
165 ERR("Error during MempSetupPaging\n");
166 }
167}
unsigned char BOOLEAN
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:171
PFN_NUMBER MmGetLoaderPagesSpanned(VOID)
Definition: mm.c:307
#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

Referenced by WinLdrSetupMemoryLayout().

◆ WinLdrInsertDescriptor()

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

Definition at line 352 of file wlmemory.c.

354{
355 PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
356 PLIST_ENTRY PreviousEntry, NextEntry;
357 PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
358
359 TRACE("BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
360 NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]);
361
362 /* Find a place where to insert the new descriptor to */
363 PreviousEntry = ListHead;
364 NextEntry = ListHead->Flink;
365 while (NextEntry != ListHead)
366 {
367 NextDescriptor = CONTAINING_RECORD(NextEntry,
369 ListEntry);
370 if (NewDescriptor->BasePage < NextDescriptor->BasePage)
371 break;
372
373 PreviousEntry = NextEntry;
374 PreviousDescriptor = NextDescriptor;
375 NextEntry = NextEntry->Flink;
376 }
377
378 /* Don't forget about merging free areas */
379 if (NewDescriptor->MemoryType != LoaderFree)
380 {
381 /* Just insert, nothing to merge */
382 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
383 }
384 else
385 {
386 /* Previous block also free? */
387 if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType == LoaderFree) &&
388 ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
389 NewDescriptor->BasePage))
390 {
391 /* Just enlarge previous descriptor's PageCount */
392 PreviousDescriptor->PageCount += NewDescriptor->PageCount;
393 NewDescriptor = PreviousDescriptor;
394 }
395 else
396 {
397 /* Nope, just insert */
398 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
399 }
400
401 /* Next block is free ?*/
402 if ((NextEntry != ListHead) &&
403 (NextDescriptor->MemoryType == LoaderFree) &&
404 ((NewDescriptor->BasePage + NewDescriptor->PageCount) == NextDescriptor->BasePage))
405 {
406 /* Enlarge next descriptor's PageCount */
407 NewDescriptor->PageCount += NextDescriptor->PageCount;
408 RemoveEntryList(&NextDescriptor->ListEntry);
409 }
410 }
411
412 return;
413}
#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:17
_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 174 of file wlmemory.c.

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

Referenced by LoadAndBootWindowsCommon().

Variable Documentation

◆ Mad

Definition at line 50 of file wlmemory.c.

Referenced by MempAddMemoryBlock(), and WinLdrSetupMemoryLayout().

◆ MadCount

ULONG MadCount = 0

Definition at line 51 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 17 of file wlmemory.c.

Referenced by WinLdrInsertDescriptor().