#ifndef _I386_STRING_H_
#define _I386_STRING_H_
+#if 0
+
/*
* On a 486 or Pentium, we are better off not using the
* byte string operations. But on a 386 or a PPro the
return addr;
}
+#endif
+
#endif
#endif
#define NR_SECTION_PAGE_TABLES (1024)
#define NR_SECTION_PAGE_ENTRIES (1024)
+#define SPE_PENDING (0x1)
+
typedef struct
{
- PVOID Pages[NR_SECTION_PAGE_ENTRIES];
+ ULONG Pages[NR_SECTION_PAGE_ENTRIES];
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
typedef struct
NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address);
+NTSTATUS MmWaitForPage(PVOID Page);
+VOID MmClearWaitPage(PVOID Page);
+VOID MmSetWaitPage(PVOID Page);
+BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address);
+BOOLEAN MmIsPageTablePresent(PVOID PAddress);
+ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address);
+ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address);
+MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
+ PVOID Address,
+ ULONG Length);
+
#endif
VOID PsFreezeOtherThread(PETHREAD Thread);
VOID PsFreezeProcessThreads(PEPROCESS Process);
VOID PsUnfreezeProcessThreads(PEPROCESS Process);
+PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
#endif
#ifndef _I386_STRING_H_
#define _I386_STRING_H_
+wchar_t* wcsdup(wchar_t* src);
+
+#if 0
+
#ifndef _LINUX_TYPES_H
#include <internal/types.h>
#endif
return addr;
}
+#endif
+
#endif
mkdir -p $1/reactos/bin
#cp fdisk.exe $1
#cp format.exe $1
-cp loaders/dos/loadros.com $1
-cp ntoskrnl/ntoskrnl.exe $1
-cp services/fs/vfat/vfatfs.sys $1
-cp services/dd/ide/ide.sys $1
+#cp loaders/dos/loadros.com $1
+#cp ntoskrnl/ntoskrnl.exe $1
+#cp services/fs/vfat/vfatfs.sys $1
+#cp services/dd/ide/ide.sys $1
+cp ntoskrnl/ntoskrnl.exe $1/reactos/system32/
+cp services/fs/vfat/vfatfs.sys $1/reactos/system32/drivers/
+cp services/dd/ide/ide.sys $1/reactos/system32/drivers/
cp services/dd/keyboard/keyboard.sys $1/reactos/system32/drivers
cp services/dd/blue/blue.sys $1/reactos/system32/drivers
#cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers
;
; $Logfile: C:/dos-c/src/boot/boot.asv $
;
-; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.asm,v 1.3 1998/08/25 04:37:43 rex Exp $
+; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.asm,v 1.4 2000/06/25 03:59:14 dwelch Exp $
;
; $Log: boot.asm,v $
+; Revision 1.4 2000/06/25 03:59:14 dwelch
+; Removed from redundant files from the mm directory
+; Added some preliminary work on the pager
+; Fixed ntoskrnl/mm/npool.c (This may have been the cause of the
+; problems reported with loading win32k.sys)
+; Fixed problems with reporting space used to store physical page
+; information
+; Added code to support MmSafeCopy{To/From}User interface work
+; (untested)
+; Added Event member of the PHYSICAL_PAGE structure to implement Philip
+; Susi's suggestion
+; Reworked section page-in code (not really tested)
+; Replaced inline string functions with gcc builtins to make debugging easier
+;
; Revision 1.3 1998/08/25 04:37:43 rex
; new release cleanup
;
#
# makefile for DOS-C boot
#
-# $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.mak,v 1.3 1998/08/25 04:39:40 rex Exp $
+# $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.mak,v 1.4 2000/06/25 03:59:14 dwelch Exp $
#
# $Log: boot.mak,v $
+# Revision 1.4 2000/06/25 03:59:14 dwelch
+# Removed from redundant files from the mm directory
+# Added some preliminary work on the pager
+# Fixed ntoskrnl/mm/npool.c (This may have been the cause of the
+# problems reported with loading win32k.sys)
+# Fixed problems with reporting space used to store physical page
+# information
+# Added code to support MmSafeCopy{To/From}User interface work
+# (untested)
+# Added Event member of the PHYSICAL_PAGE structure to implement Philip
+# Susi's suggestion
+# Reworked section page-in code (not really tested)
+# Replaced inline string functions with gcc builtins to make debugging easier
+#
# Revision 1.3 1998/08/25 04:39:40 rex
# Release cleanup
#
;
; $Logfile: C:/dos-c/src/boot/boot.asv $
;
-; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/bootbk.asm,v 1.3 1998/08/25 04:40:47 rex Exp $
+; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/bootbk.asm,v 1.4 2000/06/25 03:59:14 dwelch Exp $
;
; $Log: bootbk.asm,v $
+; Revision 1.4 2000/06/25 03:59:14 dwelch
+; Removed from redundant files from the mm directory
+; Added some preliminary work on the pager
+; Fixed ntoskrnl/mm/npool.c (This may have been the cause of the
+; problems reported with loading win32k.sys)
+; Fixed problems with reporting space used to store physical page
+; information
+; Added code to support MmSafeCopy{To/From}User interface work
+; (untested)
+; Added Event member of the PHYSICAL_PAGE structure to implement Philip
+; Susi's suggestion
+; Reworked section page-in code (not really tested)
+; Replaced inline string functions with gcc builtins to make debugging easier
+;
; Revision 1.3 1998/08/25 04:40:47 rex
; Release cleanup
;
/* FUNCTIONS ****************************************************************/
-VOID
-STDCALL
-KeClearEvent (
- PKEVENT Event
- )
+VOID STDCALL KeClearEvent (PKEVENT Event)
{
DPRINT("KeClearEvent(Event %x)\n", Event);
Event->Header.SignalState=FALSE;
}
-VOID
-STDCALL
-KeInitializeEvent (
- PKEVENT Event,
- EVENT_TYPE Type,
- BOOLEAN State
- )
+VOID STDCALL KeInitializeEvent (PKEVENT Event,
+ EVENT_TYPE Type,
+ BOOLEAN State)
{
ULONG IType;
InitializeListHead(&(Event->Header.WaitListHead));
}
-LONG
-STDCALL
-KeReadStateEvent (
- PKEVENT Event
- )
+LONG STDCALL KeReadStateEvent (PKEVENT Event)
{
return(Event->Header.SignalState);
}
-LONG
-STDCALL
-KeResetEvent (
- PKEVENT Event
- )
+LONG STDCALL KeResetEvent (PKEVENT Event)
{
return(InterlockedExchange(&(Event->Header.SignalState),0));
}
-LONG
-STDCALL
-KeSetEvent (
- PKEVENT Event,
- KPRIORITY Increment,
- BOOLEAN Wait
- )
+LONG STDCALL KeSetEvent (PKEVENT Event,
+ KPRIORITY Increment,
+ BOOLEAN Wait)
{
int ret;
-# $Id: makefile_rex,v 1.73 2000/06/18 17:39:07 ekohl Exp $
+# $Id: makefile_rex,v 1.74 2000/06/25 03:59:14 dwelch Exp $
#
# ReactOS Operating System
#
rtl/wstring.o
# Kernel (Ke)
-# Note: head.o MUST be the fist file!!!
+# Note: head.o MUST be the first file!!!
OBJECTS_KE = \
ke/head.o \
ke/apc.o \
mm/ppool.o \
mm/section.o \
mm/virtual.o \
- mm/zone.o
+ mm/zone.o \
+ mm/pager.o \
+# mm/kmap.o
OBJECTS_MM_I386 = \
mm/i386/memsafe.o \
ULONG Flags;
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
+ KEVENT Event;
} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
/* GLOBALS ****************************************************************/
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
MmPageArray[i].ReferenceCount = 1;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS;
MmPageArray[i].ReferenceCount = 1;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
MmPageArray[i].ReferenceCount = 1;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&UsedPageListHead,
&MmPageArray[i].ListEntry);
}
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
+ KeInitializeEvent(&MmPageArray[i].Event,
+ NotificationEvent,
+ FALSE);
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
DPRINT("MmAllocPage() = %x\n",offset);
return((PVOID)offset);
}
+
+NTSTATUS MmWaitForPage(PVOID Page)
+{
+ return(STATUS_SUCCESS);
+}
+
+VOID MmClearWaitPage(PVOID Page)
+{
+}
+
+VOID MmSetWaitPage(PVOID Page)
+{
+}
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/freelist.c
- * PURPOSE: Handle the list of free physical pages
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * 27/05/98: Created
- * 18/08/98: Added a fix from Robert Bergkvist
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <internal/stddef.h>
-#include <internal/mmhal.h>
-#include <internal/mm.h>
-#include <internal/ntoskrnl.h>
-#include <internal/bitops.h>
-#include <ddk/ntddk.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* TYPES *******************************************************************/
-
-#define PHYSICAL_PAGE_FREE (0x1)
-#define PHYSICAL_PAGE_INUSE (0x2)
-#define PHYSICAL_PAGE_BIOS (0x4)
-
-#define PHYSICAL_PAGE_PAGEIN (0x8)
-
-typedef struct _PHYSICAL_PAGE
-{
- ULONG Flags;
- LIST_ENTRY ListEntry;
-} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
-
-/* GLOBALS ****************************************************************/
-
-static PAGE_ARRAY[] PageArray;
-
-static LIST_ENTRY UsedPageListHead;
-static LIST_ENTRY FreePageListHead;
-static LIST_ENTRY BiosPageListHead;
-
-/* FUNCTIONS *************************************************************/
-
-PVOID MmMapKernelPage(PVOID PhysicalAddress)
-{
-
-}
-
-VOID MmInitializePageList(PVOID FirstKernelAddress,
- PVOID LastKernelAddress,
- ULONG MemorySizeInPages)
-/*
- * FUNCTION: Initializes the page list with all pages free
- * except those known to be reserved and those used by the kernel
- * ARGUMENTS:
- * PageBuffer = Page sized buffer
- * FirstKernelAddress = First physical address used by the kernel
- * LastKernelAddress = Last physical address used by the kernel
- */
-{
- PHYSICAL_PAGE PageArray[];
- ULONG i;
- ULONG Reserved;
-
- InitializeListHead(&UsedPageListHead);
- InitializeListHead(&FreePageListHead);
- InitializeListHead(&BiosPageListHead);
-
- Reserved = (MemorySizeInPages * sizeof(PHYSICAL_PAGE)) / PAGESIZE;
-
- PageArray = MmMapKernelPages(LastKernelAddress + PAGESIZE,
- Reserved);
-
- for (i=1; i<MemorySizeInPages; i++)
- {
- if (i >= (0xa0000 / PAGESIZE) &&
- i < (0x100000 / PAGESIZE))
- {
- PageArray[i].Flags = PHYSICAL_PAGE_BIOS;
- InsertTailList(&BiosPageListHead,
- &PageArray[CurrentOffset].ListEntry);
- }
- else if (i >= (FirstKernelAddress / PAGE_SIZE) &&
- i < (LastKernelAddress / PAGESIZE))
- {
- PageArray[i].Flags = PHYSICAL_PAGE_INUSE;
- InsertTailList(&UsedPageListHead,
- &PageArray[CurrentOffset].ListEntry);
- }
- else
- {
- PageArray[i].Flags = PHYSICAL_PAGE_FREE;
- InsertTailList(&UsedPageListHead,
- &PageArray[CurrentOffset].ListEntry);
- }
- }
-
-}
-
-VOID MmFreePage(PVOID PhysicalAddress,
- PVOID Nr)
-{
- ULONG i;
- ULONG Start = PhysicalAddress / PAGESIZE;
-
- for (i=0; i++; i<Nr)
- {
- PageArray[Start + i].Flags = PHYSICAL_PAGE_FREE;
- RemoveEntryList(&PageArray[Start + i].ListEntry);
- InsertTailList(&FreePageListHead, &PageArray[Start + i].ListEntry);
- }
-}
-
-PVOID MmAllocDmaPage(PVOID MaxPhysicalAddress)
-{
- ULONG i;
-
- for (i=0; i<(MaxPhysicalAddress / PAGESIZE); i++)
- {
- if (PageArray[i].Flags & PHYSICAL_PAGE_FREE)
- {
- PageDescriptor->Flags = PHYSICAL_PAGE_INUSE;
- RemoveEntryList(&PageDescriptor->ListEntry);
- InsertTailList(&UsedPageListHead,
- &PageDescriptor->ListEntry);
- return(i * PAGESIZE);
- }
- }
- return(NULL);
-}
-
-PVOID MmAllocPage(VOID)
-{
- PLIST_ENTRY ListEntry;
- PPHYSICAL_PAGE PageDescriptor;
-
- ListEntry = RemoveHeadList(&FreePageListHead);
- PageDescriptor = CONTAING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
-
- PageDescriptor->Flags = PHYSICAL_PAGE_INUSE;
- InsertTailList(&UsedPageListHead,
- ListEntry);
-
- return((PageDescriptor - PageArray) / sizeof(PHYSICAL_PAGE) * PAGESIZE);
-}
.globl _MmSafeCopyFromUser
-.globl _MmSafeCopyFromUserEnd
+.globl _MmSafeCopyFromUserUnsafeStart
+.globl _MmSafeCopyFromUserRestart
.globl _MmSafeCopyToUser
-.globl _MmSafeCopyToUserEnd
+.globl _MmSafeCopyToUserUnsafeStart
+.globl _MmSafeCopyToUserRestart
/*
* NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src,
* Default return code
*/
movl $0,%eax
-
+
+_MmSafeCopyFromUserUnsafeStart:
/*
* This is really a synthetic instruction since if we incur a
* pagefault then eax will be set to an appropiate STATUS code
*/
rep movsb
+_MmSafeCopyFromUserRestart:
+
popl %ecx
popl %edi
popl %esi
ret
-_MmSafeCopyFromUserEnd:
+/*****************************************************************************/
/*
* NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src,
* Default return code
*/
movl $0,%eax
-
+
+_MmSafeCopyToUserUnsafeStart:
/*
* This is really a synthetic instruction since if we incur a
* pagefault then eax will be set to an appropiate STATUS code
*/
rep movsb
+_MmSafeCopyToUserRestart:
+
popl %ecx
popl %edi
popl %esi
ret
-_MmSafeCopyToUserEnd:
-/* $Id: page.c,v 1.8 2000/04/07 02:24:01 dwelch Exp $
+/* $Id: page.c,v 1.9 2000/06/25 03:59:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
#define PA_BIT_PRESENT (0)
#define PA_BIT_READWRITE (1)
#define PA_BIT_USER (2)
+#define PA_BIT_DIRTY (6)
#define PA_PRESENT (1<<PA_BIT_PRESENT)
+#define PA_DIRTY (1<<PA_BIT_DIRTY)
#define PAGETABLE_MAP (0xf0000000)
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
}
}
-
+BOOLEAN MmIsPageTablePresent(PVOID PAddress)
+{
+ PULONG page_dir;
+ ULONG Address = (ULONG)PAddress;
+
+ page_dir = ADDR_TO_PDE(Address);
+ return((*page_dir) == 0);
+}
PULONG MmGetPageEntry(PVOID PAddress)
/*
return(page_tlb);
}
+BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address)
+{
+ return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
+}
+
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
{
return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT);
#define NDEBUG
#include <internal/debug.h>
+/* EXTERNS *******************************************************************/
+
+extern VOID MmSafeCopyFromUserUnsafeStart(VOID);
+extern VOID MmSafeCopyFromUserRestart(VOID);
+extern VOID MmSafeCopyToUserUnsafeStart(VOID);
+extern VOID MmSafeCopyToUserRestart(VOID);
+
/* FUNCTIONS *****************************************************************/
NTSTATUS MmPageFault(ULONG Cs,
ULONG ErrorCode)
{
KPROCESSOR_MODE Mode;
+ NTSTATUS Status;
DPRINT("MmPageFault(Eip %x, Cr2 %x, ErrorCode %x)\n",
Eip, Cr2, ErrorCode);
if (ErrorCode & 0x1)
{
- return(MmAccessFault(Mode, Cr2));
+ Status = MmAccessFault(Mode, Cr2);
}
else
{
- return(MmNotPresentFault(Mode, Cr2));
+ Status = MmNotPresentFault(Mode, Cr2);
+ }
+
+ if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
+ ((*Eip) >= (ULONG)MmSafeCopyFromUserUnsafeStart) &&
+ ((*Eip) <= (ULONG)MmSafeCopyFromUserRestart))
+ {
+ (*Eip) = (ULONG)MmSafeCopyFromUserRestart;
+ (*Eax) = STATUS_ACCESS_VIOLATION;
+ return(STATUS_SUCCESS);
+ }
+ if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
+ ((*Eip) >= (ULONG)MmSafeCopyToUserUnsafeStart) &&
+ ((*Eip) <= (ULONG)MmSafeCopyToUserRestart))
+ {
+ (*Eip) = (ULONG)MmSafeCopyToUserRestart;
+ (*Eax) = STATUS_ACCESS_VIOLATION;
+ return(STATUS_SUCCESS);
}
+ return(Status);
}
+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: mkernel/mm/lock.c
- * PURPOSE: Locking/unlocking virtual memory areas
- * PROGRAMMER: David Welch (welch@mcmail.com)
- */
-
-BOOL VirtualUnlock(LPVOID lpAddress, DWORD cbSize)
-/*
- * FUNCTION: Unlocks pages from the virtual address space of the current
- * process
- * ARGUMENTS:
- * lpAddress = Beginning of the region to unlock
- * cbSize = Size (in bytes) of the region to unlock
- * RETURNS: Success or failure
- */
-{
- return(FALSE);
-}
-
-BOOL VirtualLock(LPVOID lpvAddress, DWORD cbSize)
-/*
- * FUNCTION: Prevents range of memory from being swapped out
- * RECEIVES:
- * lpvAddress - The base of the range to lock
- * cbSize - The size of the range to lock
- * RETURNS:
- * TRUE - the function succeeds
- * FALSE - the function failed (use GetLastError for details)
- *
- * NOTES: I'm guessing the kernel loads every page as well as locking it.
- */
-{
- unsigned int first_page = PAGE_ROUND_DOWN((int)lpvAddress);
- unsigned int length = PAGE_ROUND_DOWN( ((int)lpvAddress) + cbSize) -
- first_page;
- memory_area* marea=NULL;
- memory_area* current=NULL;
- unsigned int i;
-
- /*
- * Check the process isn't trying to lock too much
- */
- if ( ((length/PAGESIZE)+1) > 30)
- {
- SetLastError(0);
- return(FALSE);
- }
-
- /*
- * Find the corresponding vmarea(s)
- */
- marea = find_first_marea(memory_area_list_head,first_page,
- length);
- if (marea==NULL)
- {
- SetLastError(0);
- return(FALSE);
- }
-
- /*
- * Check the memory areas are committed, continuous and not
- * PAGE_NOACCESS
- */
- current=marea;
- if (current->base != first_page)
- {
- SetLastError(0);
- return(FALSE);
- }
- while (current!=NULL && current->base < (first_page+length) )
- {
- if (!(current->state & MEM_COMMIT) ||
- current->access & PAGE_NOACCESS)
- {
- SetLastError(0);
- return(FALSE);
- }
- if ( current->next==NULL)
- {
- if ((current->base + current->length) !=
- (first_page+length) )
- {
- SetLastError(0);
- return(FALSE);
- }
- }
- else
- {
- if ( (current->base+current->length) !=
- current->next->base)
- {
- SetLastError(0);
- return(FALSE);
- }
- }
- current=current->next;
- }
-
- /*
- * Lock/load the areas in memory
- * (the pages aren't loaded just by touching them to avoid the
- * overhead of a page fault)
- */
- current=marea;
- while (current!=NULL && current->base < (first_page+length) )
- {
- marea->lock = TRUE;
- for (i=0; i<current->length; i++)
- {
- if (!current->load_page(marea,i))
- {
- /*
- * If the page couldn't be loaded we unlock
- * the locked pages and abort
- */
- VirtualUnlock(lpvAddress,
- current->base+i-PAGESIZE);
- SetLastError(0);
- return(FALSE);
- }
- }
- }
-
- return(TRUE);
-}
PVOID Address,
ULONG Length)
{
- MEMORY_AREA* Result;
PLIST_ENTRY current_entry;
MEMORY_AREA* current;
ULONG Extent;
}
DPRINT("Finished MmOpenMemoryAreaByRegion() = NULL\n",0);
return(NULL);
-
- return(Result);
}
static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
-/* $Id: mm.c,v 1.30 2000/05/24 22:29:36 dwelch Exp $
+/* $Id: mm.c,v 1.31 2000/06/25 03:59:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
{
}
-VOID MmInitVirtualMemory(boot_param* bp)
+VOID MmInitVirtualMemory(boot_param* bp, ULONG LastKernelAddress)
/*
* FUNCTION: Intialize the memory areas list
* ARGUMENTS:
DPRINT("MmInitVirtualMemory(%x)\n",bp);
+ LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
+
MmInitMemoryAreas();
- ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
+// ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
+ ExInitNonPagedPool(LastKernelAddress + PAGESIZE);
/*
&kernel_data_desc);
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));
- Length = ParamLength;
+// Length = ParamLength;
+ Length = LastKernelAddress - (ULONG)BaseAddress;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
0,
&kernel_param_desc);
- BaseAddress = (PVOID)(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
+ BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE);
Length = NONPAGED_POOL_SIZE;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
/*
* Intialize memory areas
*/
- MmInitVirtualMemory(bp);
+ MmInitVirtualMemory(bp, LastKernelAddress);
}
VOID MmInitSystem (ULONG Phase, boot_param* bp, ULONG LastKernelAddress)
-/* $Id: npool.c,v 1.28 2000/06/07 13:04:53 ekohl Exp $
+/* $Id: npool.c,v 1.29 2000/06/25 03:59:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
{
used_blk = (struct _block_hdr *)start;
used_blk->magic = BLOCK_HDR_MAGIC;
- used_blk->size = nr_pages * PAGESIZE;
+ used_blk->size = (nr_pages * PAGESIZE) - sizeof(block_hdr);
add_to_used_list(used_blk);
EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size;
return(block_to_address(current));
}
-//asmlinkage VOID ExFreePool(PVOID block)
-VOID
-STDCALL
-ExFreePool (
- PVOID block
- )
+VOID STDCALL ExFreePool (PVOID block)
/*
* FUNCTION: Releases previously allocated memory
* ARGUMENTS:
}
PVOID STDCALL ExAllocateNonPagedPoolWithTag(ULONG type,
- ULONG size,
- ULONG Tag,
- PVOID Caller)
+ ULONG size,
+ ULONG Tag,
+ PVOID Caller)
{
block_hdr* current = NULL;
PVOID block;
+++ /dev/null
-%include 'internal/i386/segment.inc'
-
-
-%define PREFIX(a) _(a)
-
-BITS 32
-extern PREFIX(page_fault_handler)
-extern PREFIX exception_handler
-segment .text
-
-DECLARE_GLOBAL_SYMBOL exception_handler14
- cli
- push gs
- push fs
- push es
- push ds
- push dword 14
- pushad
- mov ax,KERNEL_DS
- mov ds,ax
- mov es,ax
- mov fs,ax
- mov gs,ax
- call _page_fault_handler
- cmp eax,0
- jne _ret_from_exp
- call _exception_handler
-_ret_from_exp:
- popad
- add esp,4
- pop ds
- pop es
- pop fs
- pop gs
- add esp,4
- iretd
-
--- /dev/null
+/* $Id: pager.c,v 1.1 2000/06/25 03:59:15 dwelch Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/pager.c
+ * PURPOSE: Moves infrequently used data out of memory
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 27/05/98: Created
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <internal/mm.h>
+#include <internal/mmhal.h>
+#include <string.h>
+#include <internal/string.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+static HANDLE PagerThreadHandle;
+static CLIENT_ID PagerThreadId;
+static KEVENT PagerThreadEvent;
+static PVOID LastAddress;
+static PEPROCESS LastProcess;
+static BOOLEAN PagerThreadShouldTerminate;
+static volatile ULONG PageCount;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID MmPageOutPage(PEPROCESS Process,
+ PMEMORY_AREA marea,
+ PVOID Address)
+{
+ ULONG Count;
+
+ Count = 0;
+
+ switch(marea->Type)
+ {
+ case MEMORY_AREA_SYSTEM:
+ break;
+
+ case MEMORY_AREA_SECTION_VIEW_COMMIT:
+ Count = MmPageOutSectionView(&Process->Pcb.AddressSpace,
+ marea,
+ Address);
+ break;
+
+ case MEMORY_AREA_COMMIT:
+ Count = MmPageOutVirtualMemory(&Process->Pcb.AddressSpace,
+ marea,
+ Address);
+ break;
+
+ default:
+ break;
+ }
+ PageCount = PageCount - Count;
+}
+
+VOID MmTryPageOutFromArea(PEPROCESS Process,
+ PMEMORY_AREA marea)
+{
+ ULONG i;
+ ULONG j;
+
+ for (i = 0; i < marea->Length; i = i + 0x400000)
+ {
+ if (MmIsPageTablePresent(marea->BaseAddress + i))
+ {
+ for (j = 0; j < marea->Length; j = j + 4096)
+ {
+ if (MmIsPagePresent(NULL, marea->BaseAddress + i + j))
+ {
+ MmPageOutPage(Process,
+ marea,
+ marea->BaseAddress + i + j);
+ if (PageCount == 0)
+ {
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+VOID MmTryPageOutFromProcess(PEPROCESS Process)
+{
+ PMEMORY_AREA marea;
+
+ MmLockAddressSpace(&Process->Pcb.AddressSpace);
+ while ((ULONG)LastAddress < 0xc0000000)
+ {
+ marea = MmOpenMemoryAreaByRegion(&Process->Pcb.AddressSpace,
+ LastAddress,
+ 0xc0000000 - (ULONG)LastAddress);
+ if (marea == NULL)
+ {
+ return;
+ }
+ MmTryPageOutFromArea(Process,
+ marea);
+ LastAddress = LastAddress + marea->Length;
+ if (PageCount == 0)
+ {
+ MmUnlockAddressSpace(&Process->Pcb.AddressSpace);
+ return;
+ }
+ }
+ MmUnlockAddressSpace(&Process->Pcb.AddressSpace);
+}
+
+NTSTATUS MmPagerThreadMain(PVOID Ignored)
+{
+ NTSTATUS Status;
+
+ PageCount = 0;
+ LastAddress = 0;
+ LastProcess = PsInitialSystemProcess;
+ PagerThreadShouldTerminate = FALSE;
+ KeInitializeEvent(&PagerThreadEvent,
+ SynchronizationEvent,
+ FALSE);
+
+ for(;;)
+ {
+ Status = KeWaitForSingleObject(&PagerThreadEvent,
+ 0,
+ KernelMode,
+ FALSE,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("PagerThread: Wait failed\n");
+ KeBugCheck(0);
+ }
+ if (PagerThreadShouldTerminate)
+ {
+ DbgPrint("PagerThread: Terminating\n");
+ return(STATUS_SUCCESS);
+ }
+
+ while (PageCount > 0)
+ {
+ KeAttachProcess(LastProcess);
+ MmTryPageOutFromProcess(LastProcess);
+ KeDetachProcess();
+ if (PageCount != 0)
+ {
+ LastProcess = PsGetNextProcess(LastProcess);
+ LastAddress = 0;
+ }
+ }
+ }
+}
+
+NTSTATUS MmInitPager(VOID)
+{
+ NTSTATUS Status;
+
+ Status = PsCreateSystemThread(&PagerThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ &PagerThreadId,
+ MmPagerThreadMain,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ return(STATUS_SUCCESS);
+}
-/* $Id: section.c,v 1.31 2000/05/24 22:29:38 dwelch Exp $
+/* $Id: section.c,v 1.32 2000/06/25 03:59:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
VOID MmSetPageEntrySection(PSECTION_OBJECT Section,
ULONG Offset,
- PVOID Entry)
+ ULONG Entry)
{
PSECTION_PAGE_TABLE Table;
ULONG DirectoryOffset;
Table->Pages[TableOffset] = Entry;
}
-PVOID MmGetPageEntrySection(PSECTION_OBJECT Section,
+ULONG MmGetPageEntrySection(PSECTION_OBJECT Section,
ULONG Offset)
{
PSECTION_PAGE_TABLE Table;
- PVOID Entry;
+ ULONG Entry;
ULONG DirectoryOffset;
ULONG TableOffset;
DPRINT("Table %x\n", Table);
if (Table == NULL)
{
- return(NULL);
+ return(0);
}
TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
Entry = Table->Pages[TableOffset];
return(Entry);
}
-NTSTATUS MmOldLoadPageForSection(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* MemoryArea,
- PVOID Address)
+NTSTATUS MmUnalignedLoadPageForSection(PMADDRESS_SPACE AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address)
{
LARGE_INTEGER Offset;
IO_STATUS_BLOCK IoStatus;
}
-NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* MemoryArea,
- PVOID Address)
+NTSTATUS MmOldNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address)
{
LARGE_INTEGER Offset;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
ULONG PAddress;
PSECTION_OBJECT Section;
- PVOID Entry;
+ ULONG Entry;
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
if ((MemoryArea->Data.SectionData.ViewOffset % PAGESIZE) != 0)
{
- return(MmOldLoadPageForSection(AddressSpace, MemoryArea, Address));
+ return(MmUnalignedLoadPageForSection(AddressSpace,
+ MemoryArea,
+ Address));
}
DPRINT("MemoryArea->BaseAddress %x\n", MemoryArea->BaseAddress);
DPRINT("Entry %x\n", Entry);
- if (Entry == NULL)
+ if (Entry == 0)
{
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl);
Entry = MmGetPageEntrySection(Section, Offset.QuadPart);
- if (Entry == NULL)
+ if (Entry == 0)
{
MmSetPageEntrySection(Section,
Offset.QuadPart,
- Page);
+ (ULONG)Page);
}
else
{
MmDereferencePage(Page);
- Page = Entry;
+ Page = (PVOID)Entry;
MmReferencePage(Page);
}
}
else
{
- Page = Entry;
+ Page = (PVOID)Entry;
+ MmReferencePage(Page);
+ }
+
+ MmSetPage(NULL,
+ Address,
+ MemoryArea->Attributes,
+ (ULONG)Page);
+ MmUnlockSection(Section);
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address)
+{
+ LARGE_INTEGER Offset;
+ IO_STATUS_BLOCK IoStatus;
+ PMDL Mdl;
+ PVOID Page;
+ NTSTATUS Status;
+ ULONG PAddress;
+ PSECTION_OBJECT Section;
+ ULONG Entry;
+ ULONG Entry1;
+
+ DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
+ MemoryArea,Address);
+
+ if (MmIsPagePresent(NULL, Address))
+ {
+ DbgPrint("Page is already present\n");
+ KeBugCheck(0);
+ }
+
+ PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address));
+ Offset.QuadPart = (PAddress - (ULONG)MemoryArea->BaseAddress) +
+ MemoryArea->Data.SectionData.ViewOffset;
+
+ if ((MemoryArea->Data.SectionData.ViewOffset % PAGESIZE) != 0)
+ {
+ return(MmUnalignedLoadPageForSection(AddressSpace,
+ MemoryArea,
+ Address));
+ }
+
+ DPRINT("MemoryArea->BaseAddress %x\n", MemoryArea->BaseAddress);
+ DPRINT("MemoryArea->Data.SectionData.ViewOffset %x\n",
+ MemoryArea->Data.SectionData.ViewOffset);
+ DPRINT("Got offset %x\n", Offset.QuadPart);
+
+ Section = MemoryArea->Data.SectionData.Section;
+
+ DPRINT("Section %x\n", Section);
+
+ MmLockSection(Section);
+
+ Entry = MmGetPageEntrySection(Section, Offset.u.LowPart);
+
+ DPRINT("Entry %x\n", Entry);
+
+ if (Entry == 0)
+ {
+ Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
+ MmBuildMdlFromPages(Mdl);
+ Page = MmGetMdlPageAddress(Mdl, 0);
+
+ MmClearWaitPage(Page);
+
+ Entry = ((ULONG)Page) | SPE_PENDING;
+ MmSetPageEntrySection(Section,
+ Offset.u.LowPart,
+ Entry);
+
+ MmUnlockSection(Section);
+ MmUnlockAddressSpace(AddressSpace);
+ DPRINT("Reading file offset %x\n", Offset.QuadPart);
+ Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
+ Mdl,
+ &Offset,
+ &IoStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ MmLockAddressSpace(AddressSpace);
+ MmLockSection(Section);
+
+ Entry1 = MmGetPageEntrySection(Section, Offset.QuadPart);
+ if (Entry != Entry1)
+ {
+ DbgPrint("Someone changed ppte entry while we slept\n");
+ KeBugCheck(0);
+ }
+
+ Entry = (ULONG)Page;
+ MmSetPageEntrySection(Section,
+ Offset.QuadPart,
+ Entry);
+ MmSetWaitPage(Page);
+ }
+ else if (Entry & SPE_PENDING)
+ {
+ do
+ {
+ MmUnlockSection(Section);
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmWaitForPage((PVOID)(Entry & (~SPE_PENDING)));
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Failed to wait for page\n");
+ KeBugCheck(0);
+ }
+ MmLockAddressSpace(AddressSpace);
+ MmLockSection(Section);
+ Entry = MmGetPageEntrySection(Section,
+ Offset.u.LowPart);
+ } while (Entry & SPE_PENDING);
+
+ if (Entry == 0)
+ {
+ DbgPrint("Entry set to null while we slept\n");
+ KeBugCheck(0);
+ }
+
+ if (MmIsPagePresent(NULL, Address))
+ {
+ MmUnlockSection(Section);
+ return(STATUS_SUCCESS);
+ }
+
+ Page = (PVOID)Entry;
+ MmReferencePage(Page);
+ }
+ else
+ {
+ Page = (PVOID)Entry;
MmReferencePage(Page);
}
return(STATUS_SUCCESS);
}
+ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address)
+{
+ return(0);
+}
+
VOID MmpDeleteSection(PVOID ObjectBody)
{
DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody);
-/* $Id: virtual.c,v 1.28 2000/05/13 13:51:06 dwelch Exp $
+/* $Id: virtual.c,v 1.29 2000/06/25 03:59:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
/* FUNCTIONS ****************************************************************/
+ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address)
+{
+ PHYSICAL_ADDRESS PhysicalAddress;
+
+ if ((MemoryArea->Attributes & PAGE_READONLY) ||
+ (MemoryArea->Attributes & PAGE_EXECUTE_READ) ||
+ !MmIsPageDirty(PsGetCurrentProcess(), Address))
+ {
+ PhysicalAddress = MmGetPhysicalAddress(Address);
+
+ MmDereferencePage((PVOID)PhysicalAddress.u.LowPart);
+ MmSetPage(PsGetCurrentProcess(),
+ Address,
+ 0,
+ 0);
+ return(1);
+ }
+ return(0);
+}
+
NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address)
MemoryArea->Length == *RegionSize)
{
MemoryArea->Type = Type;
- MemoryArea->Attributes =Protect;
+ MemoryArea->Attributes = Protect;
DPRINT("*BaseAddress %x\n",*BaseAddress);
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
-/* $Id: process.c,v 1.44 2000/06/04 17:27:39 ea Exp $
+/* $Id: process.c,v 1.45 2000/06/25 03:59:17 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* FUNCTIONS *****************************************************************/
+
+PEPROCESS PsGetNextProcess(PEPROCESS OldProcess)
+{
+ KIRQL oldIrql;
+ PEPROCESS NextProcess;
+ NTSTATUS Status;
+
+ if (OldProcess == NULL)
+ {
+ return(PsInitialSystemProcess);
+ }
+
+ KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
+ NextProcess = CONTAINING_RECORD(OldProcess->Pcb.ProcessListEntry.Flink,
+ EPROCESS,
+ Pcb.ProcessListEntry);
+ KeReleaseSpinLock(&PsProcessListLock, oldIrql);
+ Status = ObReferenceObjectByPointer(NextProcess,
+ PROCESS_ALL_ACCESS,
+ PsProcessType,
+ KernelMode);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("PsGetNextProcess(): ObReferenceObjectByPointer failed\n");
+ KeBugCheck(0);
+ }
+ ObDereferenceObject(OldProcess);
+
+ return(NextProcess);
+}
+
NTSTATUS STDCALL NtOpenProcessToken(IN HANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE TokenHandle)
VOID PsInitProcessManagment(VOID)
{
- ANSI_STRING AnsiString;
+
PKPROCESS KProcess;
KIRQL oldIrql;
PsProcessType->OkayToClose = NULL;
PsProcessType->Create = NULL;
- RtlInitAnsiString(&AnsiString,"Process");
- RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
+ RtlInitUnicodeString(&PsProcessType->TypeName, L"Process");
InitializeListHead(&PsProcessListHead);
KeInitializeSpinLock(&PsProcessListLock);
-pipe \
-O2 \
-Iinclude \
- -fno-builtin $(LEAN_AND_MEAN_DEFINE) \
+ $(LEAN_AND_MEAN_DEFINE) \
$(DEFINES) -Wall \
-Wstrict-prototypes $(DEBUGGING_CFLAGS) \
$(EXTRA_CFLAGS)