Improved physical page managment

svn path=/trunk/; revision=353
This commit is contained in:
David Welch 1999-03-31 10:59:32 +00:00
parent e4bcefde7d
commit 572d45daca
21 changed files with 285 additions and 295 deletions

View file

@ -50,41 +50,13 @@ struct _KDPC;
typedef struct _KTIMER typedef struct _KTIMER
{ {
/*
* Pointers to maintain the linked list of activated timers
*/
LIST_ENTRY entry; LIST_ENTRY entry;
/*
* Absolute expiration time in system time units
*/
signed long long expire_time; signed long long expire_time;
/*
* Optional dpc associated with the timer
*/
struct _KDPC* dpc; struct _KDPC* dpc;
/*
* True if the timer is signaled
*/
BOOLEAN signaled; BOOLEAN signaled;
/*
* True if the timer is in the system timer queue
*/
BOOLEAN running; BOOLEAN running;
/*
* Type of the timer either Notification or Synchronization
*/
TIMER_TYPE type; TIMER_TYPE type;
/*
* Period of the timer in milliseconds (zero if once-only)
*/
ULONG period; ULONG period;
} KTIMER, *PKTIMER; } KTIMER, *PKTIMER;
struct _KSPIN_LOCK; struct _KSPIN_LOCK;

View file

@ -33,3 +33,7 @@ typedef struct _MDL
ULONG ByteCount; ULONG ByteCount;
ULONG ByteOffset; ULONG ByteOffset;
} MDL, *PMDL; } MDL, *PMDL;
#define MmSmallSystem (0)
#define MmMediumSystem (1)
#define MmLargeSystem (2)

View file

@ -28,23 +28,6 @@ PULONG MmGetPageEntry(PVOID Address);
#define PA_SYSTEM (0) #define PA_SYSTEM (0)
#define KERNEL_BASE (0xc0000000) #define KERNEL_BASE (0xc0000000)
#define IDMAP_BASE (0xd0000000)
/*
* Return a linear address which can be used to access the physical memory
* starting at x
*/
extern inline unsigned int physical_to_linear(unsigned int x)
{
return(x+IDMAP_BASE);
}
extern inline unsigned int linear_to_physical(unsigned int x)
{
return(x-IDMAP_BASE);
}
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t") #define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")

View file

@ -73,37 +73,6 @@ NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea); NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
NTSTATUS MmInitSectionImplementation(VOID); NTSTATUS MmInitSectionImplementation(VOID);
/*
* FUNCTION: Gets a page with a restricted max physical address (i.e.
* suitable for dma)
* RETURNS:
* The physical address of the page if it succeeds
* NULL if it fails.
* NOTES: This is very inefficent because the list isn't sorted. On the
* other hand sorting the list would be quite expensive especially if dma
* is only used infrequently. Perhaps a special cache of dma pages should
* be maintained?
*/
unsigned int get_dma_page(unsigned int max_address);
/*
* FUNCTION: Allocate a page and return its physical address
* RETURNS: The physical address of the page allocated
*/
asmlinkage unsigned int get_free_page(void);
/*
* FUNCTION: Adds pages to the free list
* ARGUMENTS:
* physical_base = Physical address of the base of the region to
* be freed
* nr = number of continuous pages to free
*/
asmlinkage void free_page(unsigned int physical_base, unsigned int nr);
void mark_page_not_writable(unsigned int vaddr);
void VirtualInit(boot_param* bp); void VirtualInit(boot_param* bp);
#define MM_LOWEST_USER_ADDRESS (4096) #define MM_LOWEST_USER_ADDRESS (4096)
@ -114,5 +83,12 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
ULONG Length, ULONG Length,
ULONG NewType, ULONG NewType,
ULONG NewAttributes); ULONG NewAttributes);
PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
PVOID LastPhysKernelAddress,
ULONG MemorySizeInPages,
ULONG LastKernelBase);
PVOID MmAllocPage(VOID);
VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr);
VOID MmDeletePageTable(PEPROCESS Process, PVOID Address);
#endif #endif

View file

@ -84,7 +84,7 @@ VOID NtInit(VOID);
/* /*
* Initalization functions (called once by main()) * Initalization functions (called once by main())
*/ */
VOID MmInitialize(boot_param* bp); VOID MmInitialize(boot_param* bp, ULONG LastKernelAddress);
VOID HalInit(boot_param* bp); VOID HalInit(boot_param* bp);
VOID IoInit(VOID); VOID IoInit(VOID);
VOID ObInit(VOID); VOID ObInit(VOID);

View file

@ -55,7 +55,7 @@ EXCEPT_OBJECTS = except/except.o
OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \ OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
$(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) $(NLS_OBJECTS) \ $(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \
$(INTERNAL_OBJECTS) $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) $(INTERNAL_OBJECTS) $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS)
kernel32.a: $(OBJECTS) kernel32.a: $(OBJECTS)

View file

@ -29,7 +29,7 @@ LOADERS = dos
# #
# Select the device drivers and filesystems you want # Select the device drivers and filesystems you want
# #
KERNEL_SERVICES = parallel keyboard blues null mouse serial sound ide \ KERNEL_SERVICES = parallel keyboard blues null mouse serial ide \
minix vfat ext2 minix vfat ext2
APPS = hello shell args APPS = hello shell args

View file

@ -12,10 +12,7 @@ __goxy
__wherex __wherex
__wherey __wherey
__getscreensize __getscreensize
free_page
get_dma_page
DbgPrint DbgPrint
printk
ExAcquireFastMutex ExAcquireFastMutex
ExAcquireFastMutexUnsafe ExAcquireFastMutexUnsafe
ExAcquireResourceExclusive ExAcquireResourceExclusive

View file

@ -65,6 +65,7 @@ static struct
#define BIOS32_SIGNATURE (('_' << 0)+('3'<<8)+('2'<<16)+('_'<<24)) #define BIOS32_SIGNATURE (('_' << 0)+('3'<<8)+('2'<<16)+('_'<<24))
#if 0
BOOL static checksum(bios32* service_entry) BOOL static checksum(bios32* service_entry)
/* /*
* FUNCTION: Checks the checksum of a bios32 service entry * FUNCTION: Checks the checksum of a bios32 service entry
@ -89,6 +90,7 @@ BOOL static checksum(bios32* service_entry)
} }
return(FALSE); return(FALSE);
} }
#endif
BOOLEAN Hal_bios32_is_service_present(ULONG service) BOOLEAN Hal_bios32_is_service_present(ULONG service)
{ {
@ -118,11 +120,13 @@ VOID Hal_bios32_probe()
* RETURNS: True if detected * RETURNS: True if detected
*/ */
{ {
return;
#if 0
int i; int i;
for (i=0xe0000;i<=0xffff0;i++) for (i=0xe0000;i<=0xffff0;i++)
{ {
bios32* service_entry = (bios32 *)physical_to_linear(i); /// bios32* service_entry = (bios32 *)physical_to_linear(i);
if ( service_entry->signature != BIOS32_SIGNATURE ) if ( service_entry->signature != BIOS32_SIGNATURE )
{ {
continue; continue;
@ -136,4 +140,5 @@ VOID Hal_bios32_probe()
bios32_indirect.address = service_entry->entry; bios32_indirect.address = service_entry->entry;
bios32_detected=TRUE; bios32_detected=TRUE;
} }
#endif
} }

View file

@ -214,11 +214,11 @@ asmlinkage void exception_handler(unsigned int edi,
__asm__("movl %%cr2,%0\n\t" __asm__("movl %%cr2,%0\n\t"
: "=d" (cr2)); : "=d" (cr2));
DbgPrint("cr2 %x\n",cr2); DbgPrint("cr2 %x\n",cr2);
for(;;);
DbgPrint("Process: %x\n",PsGetCurrentProcess()); DbgPrint("Process: %x\n",PsGetCurrentProcess());
DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread); DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread);
DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff, DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff,
gs&0xfff); gs&0xfff);
// for(;;);
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx); DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx);
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx,ebp,esi); DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx,ebp,esi);
DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags); DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags);

View file

@ -57,6 +57,20 @@ static ULONG ProtectToPTE(ULONG flProtect)
(((ULONG)v / (1024 * 1024))&(~0x3))) (((ULONG)v / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((ULONG)v / 1024)) #define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((ULONG)v / 1024))
VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
{
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeAttachProcess(Process);
}
*(ADDR_TO_PDE(Address)) = 0;
FLUSH_TLB;
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeDetachProcess();
}
}
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address) ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{ {
ULONG Entry; ULONG Entry;
@ -88,8 +102,7 @@ PULONG MmGetPageEntry(PVOID PAddress)
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir); DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
if ((*page_dir) == 0) if ((*page_dir) == 0)
{ {
// (*page_dir) = get_free_page() | (PA_READ | PA_WRITE); (*page_dir) = ((ULONG)MmAllocPage()) | 0x7;
(*page_dir) = get_free_page() | 0x7;
FLUSH_TLB; FLUSH_TLB;
} }
page_tlb = ADDR_TO_PTE(Address); page_tlb = ADDR_TO_PTE(Address);

View file

@ -28,6 +28,23 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
#define IDMAP_BASE (0xd0000000)
/*
* Return a linear address which can be used to access the physical memory
* starting at x
*/
extern inline unsigned int physical_to_linear(unsigned int x)
{
return(x+IDMAP_BASE);
}
extern inline unsigned int linear_to_physical(unsigned int x)
{
return(x-IDMAP_BASE);
}
#ifdef BOCHS_DEBUGGING #ifdef BOCHS_DEBUGGING
#define BOCHS_LOGGER_PORT (0x3ed) #define BOCHS_LOGGER_PORT (0x3ed)
#endif #endif

View file

@ -119,6 +119,7 @@ asmlinkage void _main(boot_param* _bp)
unsigned int start; unsigned int start;
unsigned int start1; unsigned int start1;
boot_param bp; boot_param bp;
unsigned int last_kernel_address;
memset((void *)&edata,0,((int)&end)-((int)&edata)); memset((void *)&edata,0,((int)&end)-((int)&edata));
@ -144,12 +145,18 @@ asmlinkage void _main(boot_param* _bp)
} }
start1 = start+PAGE_ROUND_UP(bp.module_length[1]); start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
last_kernel_address = KERNEL_BASE;
for (i=0; i<=bp.nr_files; i++)
{
last_kernel_address = last_kernel_address +
PAGE_ROUND_UP(bp.module_length[i]);
}
/* /*
* Initalize various critical subsystems * Initalize various critical subsystems
*/ */
HalInit(&bp); HalInit(&bp);
MmInitialize(&bp); MmInitialize(&bp, last_kernel_address);
KeInit(); KeInit();
ObInit(); ObInit();
PsInit(); PsInit();

View file

@ -31,6 +31,22 @@
/* GLOBALS ****************************************************************/ /* GLOBALS ****************************************************************/
#define IDMAP_BASE (0xd0000000)
/*
* Return a linear address which can be used to access the physical memory
* starting at x
*/
extern inline unsigned int physical_to_linear(unsigned int x)
{
return(x+IDMAP_BASE);
}
extern inline unsigned int linear_to_physical(unsigned int x)
{
return(x-IDMAP_BASE);
}
/* /*
* Current time * Current time
*/ */

View file

@ -3,20 +3,12 @@
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/freelist.c * FILE: ntoskrnl/mm/freelist.c
* PURPOSE: Handle the list of free physical pages * PURPOSE: Handle the list of free physical pages
* PROGRAMMER: David Welch (welch@mcmail.com) * PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY: * UPDATE HISTORY:
* 27/05/98: Created * 27/05/98: Created
* 18/08/98: Added a fix from Robert Bergkvist * 18/08/98: Added a fix from Robert Bergkvist
*/ */
/*
* NOTE: The list of free pages is implemented as an unsorted double linked
* list. This should make added or removing pages fast when you don't care
* about the physical address. Because the entirety of physical memory is
* mapped from 0xd0000000 upwards it is easy to do a mapping between
* physical and linear address.
*/
/* INCLUDES ****************************************************************/ /* INCLUDES ****************************************************************/
#include <internal/stddef.h> #include <internal/stddef.h>
@ -24,6 +16,7 @@
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#include <internal/bitops.h> #include <internal/bitops.h>
#include <internal/i386/io.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#define NDEBUG #define NDEBUG
@ -31,175 +24,175 @@
/* TYPES *******************************************************************/ /* TYPES *******************************************************************/
typedef struct _free_page #define PHYSICAL_PAGE_FREE (0x1)
/* #define PHYSICAL_PAGE_INUSE (0x2)
* PURPOSE: At the start of every region of free physical pages #define PHYSICAL_PAGE_BIOS (0x4)
*/
typedef struct _PHYSICAL_PAGE
{ {
struct _free_page* next; ULONG Flags;
struct _free_page* previous; LIST_ENTRY ListEntry;
unsigned int nr_pages; } PHYSICAL_PAGE, *PPHYSICAL_PAGE;
} free_page_hdr;
/* GLOBALS ****************************************************************/ /* GLOBALS ****************************************************************/
/* static PPHYSICAL_PAGE MmPageArray;
* PURPOSE: Points to the first page in the free list
*/ static LIST_ENTRY UsedPageListHead;
free_page_hdr* free_page_list_head=NULL; static KSPIN_LOCK UsedPageListLock;
static LIST_ENTRY FreePageListHead;
static KSPIN_LOCK FreePageListLock;
static LIST_ENTRY BiosPageListHead;
static KSPIN_LOCK BiosPageListLock;
/* FUNCTIONS *************************************************************/ /* FUNCTIONS *************************************************************/
void free_page(unsigned int physical_base, unsigned int nr) PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
PVOID LastPhysKernelAddress,
ULONG MemorySizeInPages,
ULONG LastKernelAddress)
/* /*
* FUNCTION: Add a physically continuous range of pages to the free list * FUNCTION: Initializes the page list with all pages free
* except those known to be reserved and those used by the kernel
* ARGUMENTS: * ARGUMENTS:
* physical_base = The first physical address to free * PageBuffer = Page sized buffer
* nr = the size of the region (in pages) to free * FirstKernelAddress = First physical address used by the kernel
* NOTES: This function attempts to keep the list partially unfragmented * LastKernelAddress = Last physical address used by the kernel
*/ */
{ {
unsigned int eflags; ULONG i;
free_page_hdr* hdr=NULL; ULONG Reserved;
DPRINT("Freeing %x to %x\n",physical_base,physical_base DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, "
+ (nr*PAGESIZE)); "LastPhysKernelAddress %x, "
"MemorySizeInPages %x, LastKernelAddress %x)\n",
FirstPhysKernelAddress,
LastPhysKernelAddress,
MemorySizeInPages,
LastKernelAddress);
/* InitializeListHead(&UsedPageListHead);
* This must be atomic KeInitializeSpinLock(&UsedPageListLock);
*/ InitializeListHead(&FreePageListHead);
__asm__("pushf\n\tpop %0\n\tcli\n\t" KeInitializeSpinLock(&FreePageListLock);
: "=d" (eflags)); InitializeListHead(&BiosPageListHead);
KeInitializeSpinLock(&BiosPageListLock);
/* Reserved = (MemorySizeInPages * sizeof(PHYSICAL_PAGE)) / PAGESIZE;
* MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress;
*/
hdr = (free_page_hdr *)physical_to_linear(physical_base);
DPRINT("free_page_hdr %x\n",hdr); DPRINT("Reserved %d\n", Reserved);
DPRINT("free_page_list_head %x\n",free_page_list_head);
if (free_page_list_head!=NULL) i = 1;
if ((ULONG)FirstPhysKernelAddress < 0xa0000)
{ {
free_page_list_head->previous=hdr; for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
}
hdr->next=free_page_list_head;
hdr->previous=NULL;
hdr->nr_pages = nr;
free_page_list_head=hdr;
__asm__("push %0\n\tpopf\n\t"
:
: "d" (eflags));
}
unsigned int get_dma_page(unsigned int max_address)
/*
* FUNCTION: Gets a page with a restricted max physical address (i.e.
* suitable for dma)
* ARGUMENTS:
* max_address = The maximum address usable by the caller
* RETURNS:
* The physical address of the page if it succeeds
* NULL if it fails.
* NOTES: This is very inefficent because the list isn't sorted. On the
* other hand sorting the list would be quite expensive especially if dma
* is only used infrequently. Perhaps a special cache of dma pages should
* be maintained?
*/
{
free_page_hdr* current=NULL;
if (free_page_list_head==NULL)
{
printk("CRITICAL: Unable to allocate page\n");
KeBugCheck(KBUG_OUT_OF_MEMORY);
}
/*
* Walk the free page list looking for suitable memory
*/
current = free_page_list_head;
while (current!=NULL)
{
if ( ((int)current) < max_address)
{ {
/* MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
* We take the first page from the region InsertTailList(&FreePageListHead,
*/ &MmPageArray[i].ListEntry);
free_page_hdr* nhdr = (free_page_hdr *)(((int)current)+PAGESIZE); }
if (current->previous!=NULL) for (; i<(0xa0000 / PAGESIZE); i++)
{ {
current->previous->next=nhdr; MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
} InsertTailList(&UsedPageListHead,
if (current->next!=NULL) &MmPageArray[i].ListEntry);
{ }
current->next->previous=nhdr; for (; i<(0x100000 / PAGESIZE); i++)
} {
nhdr->next=current->next; MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS;
nhdr->previous=current->previous; InsertTailList(&BiosPageListHead,
nhdr->nr_pages=current->nr_pages-1; &MmPageArray[i].ListEntry);
if (free_page_list_head==current)
{
free_page_list_head=nhdr;
}
return ((int)current);
} }
current=current->next;
}
return(NULL);
}
unsigned int get_free_page(void)
/*
* FUNCTION: Allocates a page
* RETURNS: The physical address of the page allocated
*/
{
unsigned int addr;
/*
* This must be atomic wrt everything
*/
unsigned int eflags;
__asm__("pushf\n\tpop %0\n\tcli\n\t"
: "=d" (eflags));
/*
* If we are totally out of memory then panic
*/
if (free_page_list_head==NULL)
{
printk("CRITICAL: Unable to allocate page\n");
KeBugCheck(KBUG_OUT_OF_MEMORY);
}
addr = 0;
if (free_page_list_head->nr_pages>1)
{
free_page_list_head->nr_pages--;
addr = ((unsigned int)free_page_list_head) +
(free_page_list_head->nr_pages * PAGESIZE);
} }
else else
{ {
addr = (unsigned int)free_page_list_head; for (; i<(0xa0000 / PAGESIZE); i++)
free_page_list_head = free_page_list_head -> next; {
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
for (; i<(0x100000 / PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS;
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
for (; i<((ULONG)LastPhysKernelAddress/PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
} }
__asm__("push %0\n\tpopf\n\t" for (; i<MemorySizeInPages; i++)
: {
: "d" (eflags)); MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
DPRINT("\nMmInitializePageList() = %x\n",
LastKernelAddress + Reserved * PAGESIZE);
return((PVOID)(LastKernelAddress + Reserved * PAGESIZE));
}
addr = addr - (IDMAP_BASE); VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
DPRINT("allocated %x\n",addr); {
ULONG i;
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
KIRQL oldIrql;
return(addr); DPRINT("MmFreePage(PhysicalAddress %x, Nr %x)\n", PhysicalAddress, Nr);
for (i=0; i<Nr; i++)
{
KeAcquireSpinLock(&UsedPageListLock, &oldIrql);
RemoveEntryList(&MmPageArray[Start + i].ListEntry);
MmPageArray[Start + i].Flags = PHYSICAL_PAGE_FREE;
KeReleaseSpinLock(&UsedPageListLock, oldIrql);
ExInterlockedInsertTailList(&FreePageListHead,
&MmPageArray[Start + i].ListEntry,
&FreePageListLock);
}
} }
PVOID MmAllocPage(VOID)
{
ULONG offset;
PLIST_ENTRY ListEntry;
PPHYSICAL_PAGE PageDescriptor;
DPRINT("MmAllocPage()\n");
ListEntry = ExInterlockedRemoveHeadList(&FreePageListHead,
&FreePageListLock);
DPRINT("ListEntry %x\n",ListEntry);
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
if (PageDescriptor == NULL)
{
return(NULL);
}
DPRINT("PageDescriptor %x\n",PageDescriptor);
PageDescriptor->Flags = PHYSICAL_PAGE_INUSE;
ExInterlockedInsertTailList(&UsedPageListHead, ListEntry,
&UsedPageListLock);
DPRINT("PageDescriptor %x MmPageArray %x\n", PageDescriptor, MmPageArray);
offset = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray);
DPRINT("offset %x\n",offset);
offset = offset / sizeof(PHYSICAL_PAGE) * PAGESIZE;
DPRINT("offset %x\n",offset);
DPRINT("MmAllocPage() = %x\n",offset);
return((PVOID)offset);
}

View file

@ -395,6 +395,7 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
MEMORY_AREA* MemoryArea; MEMORY_AREA* MemoryArea;
ULONG i; ULONG i;
KIRQL oldlvl; KIRQL oldlvl;
LARGE_INTEGER PhysicalAddr;
DPRINT("MmFreeMemoryArea(Process %x, BaseAddress %x, Length %x," DPRINT("MmFreeMemoryArea(Process %x, BaseAddress %x, Length %x,"
"FreePages %d)\n",Process,BaseAddress,Length,FreePages); "FreePages %d)\n",Process,BaseAddress,Length,FreePages);
@ -412,9 +413,10 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
{ {
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++) for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
{ {
free_page(GET_LARGE_INTEGER_LOW_PART( PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress +
MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE))), (i*PAGESIZE));
1); MmFreePage((PVOID)(ULONG)
(GET_LARGE_INTEGER_LOW_PART(PhysicalAddr)), 1);
} }
} }
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++) for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mm.c * FILE: ntoskrnl/mm/mm.c
* PURPOSE: kernel memory managment functions * PURPOSE: kernel memory managment functions
* PROGRAMMER: David Welch * PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 9/4/98 * Created 9/4/98
*/ */
@ -37,39 +37,38 @@ extern unsigned int stext;
extern unsigned int etext; extern unsigned int etext;
extern unsigned int end; extern unsigned int end;
static BOOLEAN IsThisAnNtAsSystem = FALSE;
static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
BOOLEAN MmIsThisAnNtAsSystem() BOOLEAN MmIsThisAnNtAsSystem(VOID)
{ {
UNIMPLEMENTED return(IsThisAnNtAsSystem);
} }
MM_SYSTEM_SIZE MmQuerySystemSize() MM_SYSTEM_SIZE MmQuerySystemSize(VOID)
{ {
UNIMPLEMENTED; return(MmSystemSize);
} }
void MmInitialize(boot_param* bp) void MmInitialize(boot_param* bp, ULONG LastKernelAddress)
/* /*
* FUNCTION: Initalize memory managment * FUNCTION: Initalize memory managment
*/ */
{ {
unsigned int kernel_len = bp->end_mem - bp->start_mem;
unsigned int first_krnl_phys_addr; unsigned int first_krnl_phys_addr;
unsigned int last_krnl_phys_addr; unsigned int last_krnl_phys_addr;
int i; int i;
PULONG page_directory = (PULONG)physical_to_linear( unsigned int kernel_len;
(ULONG)get_page_directory());
DPRINT("InitalizeMM()\n"); DPRINT("MmInitialize(bp %x, LastKernelAddress %x)\n", bp,
LastKernelAddress);
CHECKPOINT;
/* /*
* Unmap low memory * Unmap low memory
*/ */
page_directory[0]=0; MmDeletePageTable(NULL, 0);
FLUSH_TLB;
CHECKPOINT;
/* /*
* Free all pages not used for kernel memory * Free all pages not used for kernel memory
@ -84,23 +83,12 @@ void MmInitialize(boot_param* bp)
/* /*
* Free physical memory not used by the kernel * Free physical memory not used by the kernel
*/ */
if (first_krnl_phys_addr < 0xa0000) LastKernelAddress = (ULONG)MmInitializePageList(
{ (PVOID)first_krnl_phys_addr,
free_page(0x2000,(first_krnl_phys_addr/PAGESIZE)-2); (PVOID)last_krnl_phys_addr,
free_page(last_krnl_phys_addr+PAGESIZE, 1024,
(0xa0000 - last_krnl_phys_addr - PAGESIZE)/PAGESIZE); PAGE_ROUND_UP(LastKernelAddress));
free_page(1024*1024,EXTENDED_MEMORY_SIZE/4096); kernel_len = last_krnl_phys_addr - first_krnl_phys_addr;
}
else
{
free_page(0x2000,(0xa0000/PAGESIZE)-2);
free_page(1024*1024,
(first_krnl_phys_addr-(1024*1024))/PAGESIZE);
free_page(last_krnl_phys_addr+PAGESIZE,
((EXTENDED_MEMORY_SIZE+(1024*1024))
-last_krnl_phys_addr)/PAGESIZE);
}
CHECKPOINT;
/* /*
* Create a trap for null pointer references and protect text * Create a trap for null pointer references and protect text
@ -115,17 +103,17 @@ void MmInitialize(boot_param* bp)
(PVOID)i, (PVOID)i,
PAGE_EXECUTE_READ); PAGE_EXECUTE_READ);
} }
DPRINT("end %x\n",(int)&end);
for (i=PAGE_ROUND_UP(KERNEL_BASE+kernel_len);
i<(KERNEL_BASE+PAGE_TABLE_SIZE);i=i+PAGESIZE)
{
MmSetPage(NULL,
(PVOID)i,
PAGE_NOACCESS,
0);
}
FLUSH_TLB;
DPRINT("Invalidating between %x and %x\n",
LastKernelAddress,
KERNEL_BASE + PAGE_TABLE_SIZE);
for (i=(LastKernelAddress);
i<(KERNEL_BASE + PAGE_TABLE_SIZE);
i=i+PAGESIZE)
{
MmSetPage(NULL, (PVOID)(i), PAGE_NOACCESS, 0);
}
DPRINT("Almost done MmInit()\n");
/* /*
* Intialize memory areas * Intialize memory areas
*/ */

View file

@ -101,7 +101,7 @@ PVOID ExAllocatePage(VOID)
MmSetPage(NULL, MmSetPage(NULL,
(PVOID)addr, (PVOID)addr,
PAGE_READWRITE, PAGE_READWRITE,
get_free_page()); (ULONG)MmAllocPage());
KeReleaseSpinLock(&AllocMapLock, oldlvl); KeReleaseSpinLock(&AllocMapLock, oldlvl);
return((PVOID)addr); return((PVOID)addr);
} }
@ -459,7 +459,7 @@ static block_hdr* grow_kernel_pool(unsigned int size)
MmSetPage(NULL, MmSetPage(NULL,
(PVOID)(start + (i*PAGESIZE)), (PVOID)(start + (i*PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
get_free_page()); (ULONG)MmAllocPage());
} }

View file

@ -45,7 +45,7 @@ PVOID MmAllocateSection(ULONG Length)
MmSetPage(NULL, MmSetPage(NULL,
Result+(i*PAGESIZE), Result+(i*PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
get_free_page()); (ULONG)MmAllocPage());
} }
return((PVOID)Result); return((PVOID)Result);
} }
@ -93,7 +93,8 @@ PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress,
MmSetPage(NULL, MmSetPage(NULL,
Result + (i * PAGESIZE), Result + (i * PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
GET_LARGE_INTEGER_LOW_PART(PhysicalAddress)); GET_LARGE_INTEGER_LOW_PART(PhysicalAddress) +
(i * PAGESIZE));
} }
return((PVOID)Result); return((PVOID)Result);
} }
@ -128,7 +129,7 @@ PVOID MmAllocateNonCachedMemory(ULONG NumberOfBytes)
MmSetPage(NULL, MmSetPage(NULL,
Result+(i*PAGESIZE), Result+(i*PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
get_free_page()); (ULONG)MmAllocPage());
} }
return((PVOID)Result); return((PVOID)Result);
} }

View file

@ -98,7 +98,7 @@ ULONG MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
MmSetPage(PsGetCurrentProcess(), MmSetPage(PsGetCurrentProcess(),
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
get_free_page()); (ULONG)MmAllocPage());
return(TRUE); return(TRUE);
} }
@ -113,7 +113,7 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
MmSetPage(NULL, MmSetPage(NULL,
Address, Address,
MemoryArea->Attributes, MemoryArea->Attributes,
get_free_page()); (ULONG)MmAllocPage());
LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) + LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) +
MemoryArea->Data.SectionData.ViewOffset; MemoryArea->Data.SectionData.ViewOffset;

View file

@ -29,6 +29,22 @@ POBJECT_TYPE PsProcessType = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#define IDMAP_BASE (0xd0000000)
/*
* Return a linear address which can be used to access the physical memory
* starting at x
*/
extern inline unsigned int physical_to_linear(unsigned int x)
{
return(x+IDMAP_BASE);
}
extern inline unsigned int linear_to_physical(unsigned int x)
{
return(x-IDMAP_BASE);
}
PEPROCESS PsGetSystemProcess(VOID) PEPROCESS PsGetSystemProcess(VOID)
{ {
return(SystemProcess); return(SystemProcess);
@ -195,7 +211,7 @@ NTSTATUS STDCALL ZwCreateProcess(
InheritObjectTable, InheritObjectTable,
Process); Process);
PhysicalPageDirectory = (PULONG)get_free_page(); PhysicalPageDirectory = (PULONG)MmAllocPage();
PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory); PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory);
KProcess->PageTableDirectory = PhysicalPageDirectory; KProcess->PageTableDirectory = PhysicalPageDirectory;