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

View file

@ -33,3 +33,7 @@ typedef struct _MDL
ULONG ByteCount;
ULONG ByteOffset;
} 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 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")

View file

@ -73,37 +73,6 @@ NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
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);
#define MM_LOWEST_USER_ADDRESS (4096)
@ -114,5 +83,12 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
ULONG Length,
ULONG NewType,
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

View file

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

View file

@ -55,7 +55,7 @@ EXCEPT_OBJECTS = except/except.o
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)
kernel32.a: $(OBJECTS)

View file

@ -29,7 +29,7 @@ LOADERS = dos
#
# 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
APPS = hello shell args

View file

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

View file

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

View file

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

View file

@ -57,6 +57,20 @@ static ULONG ProtectToPTE(ULONG flProtect)
(((ULONG)v / (1024 * 1024))&(~0x3)))
#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 Entry;
@ -88,8 +102,7 @@ PULONG MmGetPageEntry(PVOID PAddress)
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
if ((*page_dir) == 0)
{
// (*page_dir) = get_free_page() | (PA_READ | PA_WRITE);
(*page_dir) = get_free_page() | 0x7;
(*page_dir) = ((ULONG)MmAllocPage()) | 0x7;
FLUSH_TLB;
}
page_tlb = ADDR_TO_PTE(Address);

View file

@ -28,6 +28,23 @@
/* 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
#define BOCHS_LOGGER_PORT (0x3ed)
#endif

View file

@ -119,6 +119,7 @@ asmlinkage void _main(boot_param* _bp)
unsigned int start;
unsigned int start1;
boot_param bp;
unsigned int last_kernel_address;
memset((void *)&edata,0,((int)&end)-((int)&edata));
@ -143,13 +144,19 @@ asmlinkage void _main(boot_param* _bp)
for(;;);
}
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
*/
HalInit(&bp);
MmInitialize(&bp);
MmInitialize(&bp, last_kernel_address);
KeInit();
ObInit();
PsInit();

View file

@ -31,6 +31,22 @@
/* 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
*/

View file

@ -3,20 +3,12 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/freelist.c
* PURPOSE: Handle the list of free physical pages
* PROGRAMMER: David Welch (welch@mcmail.com)
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 27/05/98: Created
* 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 ****************************************************************/
#include <internal/stddef.h>
@ -24,6 +16,7 @@
#include <internal/mm.h>
#include <internal/ntoskrnl.h>
#include <internal/bitops.h>
#include <internal/i386/io.h>
#include <ddk/ntddk.h>
#define NDEBUG
@ -31,175 +24,175 @@
/* TYPES *******************************************************************/
typedef struct _free_page
/*
* PURPOSE: At the start of every region of free physical pages
*/
#define PHYSICAL_PAGE_FREE (0x1)
#define PHYSICAL_PAGE_INUSE (0x2)
#define PHYSICAL_PAGE_BIOS (0x4)
typedef struct _PHYSICAL_PAGE
{
struct _free_page* next;
struct _free_page* previous;
unsigned int nr_pages;
} free_page_hdr;
ULONG Flags;
LIST_ENTRY ListEntry;
} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
/* GLOBALS ****************************************************************/
/*
* PURPOSE: Points to the first page in the free list
*/
free_page_hdr* free_page_list_head=NULL;
static PPHYSICAL_PAGE MmPageArray;
static LIST_ENTRY UsedPageListHead;
static KSPIN_LOCK UsedPageListLock;
static LIST_ENTRY FreePageListHead;
static KSPIN_LOCK FreePageListLock;
static LIST_ENTRY BiosPageListHead;
static KSPIN_LOCK BiosPageListLock;
/* 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:
* physical_base = The first physical address to free
* nr = the size of the region (in pages) to free
* NOTES: This function attempts to keep the list partially unfragmented
* PageBuffer = Page sized buffer
* FirstKernelAddress = First physical address used by the kernel
* LastKernelAddress = Last physical address used by the kernel
*/
{
unsigned int eflags;
free_page_hdr* hdr=NULL;
DPRINT("Freeing %x to %x\n",physical_base,physical_base
+ (nr*PAGESIZE));
ULONG i;
ULONG Reserved;
/*
* This must be atomic
*/
__asm__("pushf\n\tpop %0\n\tcli\n\t"
: "=d" (eflags));
DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, "
"LastPhysKernelAddress %x, "
"MemorySizeInPages %x, LastKernelAddress %x)\n",
FirstPhysKernelAddress,
LastPhysKernelAddress,
MemorySizeInPages,
LastKernelAddress);
/*
*
*/
hdr = (free_page_hdr *)physical_to_linear(physical_base);
InitializeListHead(&UsedPageListHead);
KeInitializeSpinLock(&UsedPageListLock);
InitializeListHead(&FreePageListHead);
KeInitializeSpinLock(&FreePageListLock);
InitializeListHead(&BiosPageListHead);
KeInitializeSpinLock(&BiosPageListLock);
DPRINT("free_page_hdr %x\n",hdr);
DPRINT("free_page_list_head %x\n",free_page_list_head);
Reserved = (MemorySizeInPages * sizeof(PHYSICAL_PAGE)) / PAGESIZE;
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;
}
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)
for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
{
/*
* We take the first page from the region
*/
free_page_hdr* nhdr = (free_page_hdr *)(((int)current)+PAGESIZE);
if (current->previous!=NULL)
{
current->previous->next=nhdr;
}
if (current->next!=NULL)
{
current->next->previous=nhdr;
}
nhdr->next=current->next;
nhdr->previous=current->previous;
nhdr->nr_pages=current->nr_pages-1;
if (free_page_list_head==current)
{
free_page_list_head=nhdr;
}
return ((int)current);
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
for (; i<(0xa0000 / PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
for (; i<(0x100000 / PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS;
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
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
{
addr = (unsigned int)free_page_list_head;
free_page_list_head = free_page_list_head -> next;
for (; i<(0xa0000 / PAGESIZE); i++)
{
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);
DPRINT("allocated %x\n",addr);
for (; i<MemorySizeInPages; i++)
{
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);
}

View file

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

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mm.c
* PURPOSE: kernel memory managment functions
* PROGRAMMER: David Welch
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 9/4/98
*/
@ -37,39 +37,38 @@ extern unsigned int stext;
extern unsigned int etext;
extern unsigned int end;
static BOOLEAN IsThisAnNtAsSystem = FALSE;
static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
/* 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
*/
{
unsigned int kernel_len = bp->end_mem - bp->start_mem;
unsigned int first_krnl_phys_addr;
unsigned int last_krnl_phys_addr;
int i;
PULONG page_directory = (PULONG)physical_to_linear(
(ULONG)get_page_directory());
unsigned int kernel_len;
DPRINT("InitalizeMM()\n");
DPRINT("MmInitialize(bp %x, LastKernelAddress %x)\n", bp,
LastKernelAddress);
CHECKPOINT;
/*
* Unmap low memory
*/
page_directory[0]=0;
FLUSH_TLB;
CHECKPOINT;
MmDeletePageTable(NULL, 0);
/*
* 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
*/
if (first_krnl_phys_addr < 0xa0000)
{
free_page(0x2000,(first_krnl_phys_addr/PAGESIZE)-2);
free_page(last_krnl_phys_addr+PAGESIZE,
(0xa0000 - last_krnl_phys_addr - PAGESIZE)/PAGESIZE);
free_page(1024*1024,EXTENDED_MEMORY_SIZE/4096);
}
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;
LastKernelAddress = (ULONG)MmInitializePageList(
(PVOID)first_krnl_phys_addr,
(PVOID)last_krnl_phys_addr,
1024,
PAGE_ROUND_UP(LastKernelAddress));
kernel_len = last_krnl_phys_addr - first_krnl_phys_addr;
/*
* Create a trap for null pointer references and protect text
@ -115,17 +103,17 @@ void MmInitialize(boot_param* bp)
(PVOID)i,
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
*/

View file

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

View file

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

View file

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

View file

@ -29,6 +29,22 @@ POBJECT_TYPE PsProcessType = NULL;
/* 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)
{
return(SystemProcess);
@ -195,7 +211,7 @@ NTSTATUS STDCALL ZwCreateProcess(
InheritObjectTable,
Process);
PhysicalPageDirectory = (PULONG)get_free_page();
PhysicalPageDirectory = (PULONG)MmAllocPage();
PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory);
KProcess->PageTableDirectory = PhysicalPageDirectory;