ReactOS  0.4.14-dev-599-g2d4d3f5
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 */
89  if (MadCount >= MAX_MAD_COUNT)
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:6
ULONG MadCount
Definition: wlmemory.c:58
MEMORY_ALLOCATION_DESCRIPTOR * Mad
Definition: wlmemory.c:57
TYPE_OF_MEMORY MemoryType
Definition: arc.h:193
#define MAX_MAD_COUNT
Definition: wlmemory.c:60
#define TRACE(s)
Definition: solgame.cpp:4
#define ERR(fmt,...)
Definition: debug.h:109
static VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
Definition: wlmemory.c:356

Referenced by WinLdrSetupMemoryLayout().

◆ MempSetupPagingForRegion()

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

Definition at line 106 of file wlmemory.c.

110 {
111  BOOLEAN Status = TRUE;
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 */
122  case LoaderLoadedProgram:
123  case LoaderOsloaderStack:
125  /* Map these pages into user mode */
126  Status = MempSetupPaging(BasePage, PageCount, FALSE);
127  break;
128 
129  /* Pages used by the kernel */
131  case LoaderSystemBlock:
133  case LoaderSystemCode:
134  case LoaderHalCode:
135  case LoaderBootDriver:
143  case LoaderRegistryData:
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 */
158  case LoaderSpecialMemory:
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 }
#define TRUE
Definition: types.h:120
Type
Definition: Type.h:6
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:170
Definition: arc.h:130
unsigned char BOOLEAN
#define TRACE(s)
Definition: solgame.cpp:4
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
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 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:29
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
TYPE_OF_MEMORY MemoryType
Definition: arc.h:193
static const PCSTR MemTypeDesc[]
Definition: wlmemory.c:19
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define TRACE(s)
Definition: solgame.cpp:4
Definition: typedefs.h:117

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
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define TRUE
Definition: types.h:120
ULONG MadCount
Definition: wlmemory.c:58
VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry)
BIOS_MEMORY_MAP MemoryMap[32]
Definition: loader.c:11
TYPE_OF_MEMORY MemoryType
Definition: mm.h:38
VOID MempSetupPagingForRegion(PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:106
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:170
MEMORY_ALLOCATION_DESCRIPTOR * Mad
Definition: wlmemory.c:57
TYPE_OF_MEMORY MemoryType
Definition: arc.h:193
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
ULONG PFN_NUMBER
Definition: ke.h:8
#define MAX_MAD_COUNT
Definition: wlmemory.c:60
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:320
smooth NULL
Definition: ftsmooth.c:416
PFN_NUMBER BasePage
Definition: mm.h:39
ULONG BiosMemoryMapEntryCount
Definition: meminit.c:34
#define TRACE(s)
Definition: solgame.cpp:4
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries)
Definition: mm.c:297
VOID FrLdrHeapCleanupAll(VOID)
Definition: heap.c:248
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
Definition: meminit.c:33
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1006
Status
Definition: gdiplustypes.h:24
VOID MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:65
#define ERR(fmt,...)
Definition: debug.h:109
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
static VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
Definition: wlmemory.c:356
PFN_NUMBER PageCount
Definition: mm.h:40

Referenced by LoadAndBootWindowsCommon().

Variable Documentation

◆ BiosMemoryMap

◆ BiosMemoryMapEntryCount

ULONG BiosMemoryMapEntryCount

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

Definition at line 31 of file meminit.c.

Referenced by WinLdrSetupMemoryLayout().

◆ MmLowestPhysicalPage

PFN_NUMBER MmLowestPhysicalPage

Definition at line 30 of file meminit.c.