mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Improved physical page managment
svn path=/trunk/; revision=353
This commit is contained in:
parent
e4bcefde7d
commit
572d45daca
21 changed files with 285 additions and 295 deletions
|
@ -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;
|
||||||
|
ULONG period;
|
||||||
/*
|
|
||||||
* Period of the timer in milliseconds (zero if once-only)
|
|
||||||
*/
|
|
||||||
ULONG period;
|
|
||||||
|
|
||||||
} KTIMER, *PKTIMER;
|
} KTIMER, *PKTIMER;
|
||||||
|
|
||||||
struct _KSPIN_LOCK;
|
struct _KSPIN_LOCK;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
@ -143,13 +144,19 @@ asmlinkage void _main(boot_param* _bp)
|
||||||
for(;;);
|
for(;;);
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
|
||||||
+ (nr*PAGESIZE));
|
|
||||||
|
|
||||||
/*
|
DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, "
|
||||||
* This must be atomic
|
"LastPhysKernelAddress %x, "
|
||||||
*/
|
"MemorySizeInPages %x, LastKernelAddress %x)\n",
|
||||||
__asm__("pushf\n\tpop %0\n\tcli\n\t"
|
FirstPhysKernelAddress,
|
||||||
: "=d" (eflags));
|
LastPhysKernelAddress,
|
||||||
|
MemorySizeInPages,
|
||||||
|
LastKernelAddress);
|
||||||
|
|
||||||
/*
|
InitializeListHead(&UsedPageListHead);
|
||||||
*
|
KeInitializeSpinLock(&UsedPageListLock);
|
||||||
*/
|
InitializeListHead(&FreePageListHead);
|
||||||
hdr = (free_page_hdr *)physical_to_linear(physical_base);
|
KeInitializeSpinLock(&FreePageListLock);
|
||||||
|
InitializeListHead(&BiosPageListHead);
|
||||||
|
KeInitializeSpinLock(&BiosPageListLock);
|
||||||
|
|
||||||
DPRINT("free_page_hdr %x\n",hdr);
|
Reserved = (MemorySizeInPages * sizeof(PHYSICAL_PAGE)) / PAGESIZE;
|
||||||
DPRINT("free_page_list_head %x\n",free_page_list_head);
|
MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress;
|
||||||
|
|
||||||
if (free_page_list_head!=NULL)
|
DPRINT("Reserved %d\n", Reserved);
|
||||||
|
|
||||||
|
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"
|
|
||||||
:
|
|
||||||
: "d" (eflags));
|
|
||||||
|
|
||||||
addr = addr - (IDMAP_BASE);
|
for (; i<MemorySizeInPages; i++)
|
||||||
DPRINT("allocated %x\n",addr);
|
{
|
||||||
|
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
|
||||||
|
InsertTailList(&FreePageListHead,
|
||||||
|
&MmPageArray[i].ListEntry);
|
||||||
|
}
|
||||||
|
DPRINT("\nMmInitializePageList() = %x\n",
|
||||||
|
LastKernelAddress + Reserved * PAGESIZE);
|
||||||
|
return((PVOID)(LastKernelAddress + Reserved * PAGESIZE));
|
||||||
|
}
|
||||||
|
|
||||||
return(addr);
|
VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue