Began improvements to memory managment, changed method of

mapping page tables and directories to be more efficent. These
changes require you to update your version of loadros.com

svn path=/trunk/; revision=348
This commit is contained in:
David Welch 1999-03-30 12:55:31 +00:00
parent dff0889c02
commit bbc8fd7b21
29 changed files with 392 additions and 226 deletions

View file

@ -9,6 +9,7 @@ typedef enum _EVENT_TYPE
NotificationEvent,
SynchronizationEvent,
SemaphoreType,
ProcessType,
} EVENT_TYPE;
typedef enum _KWAIT_REASON

View file

@ -173,32 +173,15 @@ typedef struct _KDPC
* PURPOSE: Defines a delayed procedure call object
*/
{
/*
* PURPOSE: Magic value to check this is the current object type
*/
SHORT Type;
/*
* PURPOSE: Target processor or zero if untargetted
*/
UCHAR Number;
/*
* PURPOSE: Indication of desired latency before exection
*/
UCHAR Importance;
UCHAR Importance;
LIST_ENTRY DpcListEntry;
PKDEFERRED_ROUTINE DeferredRoutine;
PVOID DeferredContext;
PVOID SystemArgument1;
PVOID SystemArgument2;
/*
* PURPOSE: If non-zero then already in queue
*/
PULONG Lock;
} KDPC, *PKDPC;

View file

@ -233,6 +233,13 @@ typedef struct _ETHREAD {
LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func
UCHAR LpcExitThreadCalled;
UCHAR HardErrorsAreDisabled;
/*
* Added by David Welch (welch@cwcom.net)
*/
struct _EPROCESS* OldProcess;
} ETHREAD, *PETHREAD;

View file

@ -57,14 +57,6 @@ extern inline unsigned int linear_to_physical(unsigned int x)
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")
extern inline unsigned int* get_page_directory(void)
{
unsigned int page_dir=0;
__asm__("movl %%cr3,%0\n\t"
: "=r" (page_dir));
return((unsigned int *)physical_to_linear(page_dir));
}
/*
* Amount of memory that can be mapped by a page table

View file

@ -9,7 +9,7 @@
#define PAGESIZE (4096)
PULONG MmGetPageEntry(PEPROCESS Process, PVOID Address);
PULONG MmGetPageEntry(PVOID Address);
/*
@ -48,12 +48,12 @@ extern inline unsigned int linear_to_physical(unsigned int x)
#define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t")
extern inline unsigned int* get_page_directory(void)
extern inline PULONG get_page_directory(void)
{
unsigned int page_dir=0;
__asm__("movl %%cr3,%0\n\t"
: "=r" (page_dir));
return((unsigned int *)physical_to_linear(page_dir));
return((PULONG)page_dir);
}

View file

@ -17,8 +17,7 @@
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait);
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait);
VOID KeDispatcherObjectWake(DISPATCHER_HEADER* hdr);
VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr);
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr);
VOID KiInterruptDispatch(ULONG irq);
VOID KiDispatchInterrupt(ULONG irq);

View file

@ -53,7 +53,7 @@ enum
*/
void HalInitFirstTask(PETHREAD thread);
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
void HalTaskSwitch(PKTHREAD thread);
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
NTSTATUS HalReleaseTask(PETHREAD Thread);

View file

@ -82,8 +82,8 @@ VOID LdrStartup(HANDLE SectionHandle,
NTSTATUS Status;
PIMAGE_NT_HEADERS NTHeaders;
DPRINT("LdrStartup(ImageBase %x, SectionHandle %x, "
"NTDllSectionHandle %x)\n",ImageBase,
dprintf("LdrStartup(ImageBase %x, SectionHandle %x, "
"NTDllSectionHandle %x)\n",ImageBase,
SectionHandle, NTDllSectionHandle);
LdrDllListHead.BaseAddress = (PVOID)&_image_base__;

View file

@ -538,7 +538,14 @@ l10:
add eax,07h
mov [fs:di],eax
mov [fs:di+(0xd0000000/(1024*1024))],eax
;
; Map the page tables from the page table
;
mov eax,[kernel_page_directory_base]
add eax,07h
mov [fs:di+(0xf0000000/(1024*1024))],eax
;
; Map in the kernel page table
;

View file

@ -31,6 +31,8 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#include <internal/debug.h>

View file

@ -210,9 +210,12 @@ asmlinkage void exception_handler(unsigned int edi,
{
DbgPrint("Exception: %d(%x)\n",type,error_code&0xffff);
}
DbgPrint("Process: %x\n",PsGetCurrentThread()->Cid.UniqueProcess);
DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread);
DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip);
__asm__("movl %%cr2,%0\n\t"
: "=d" (cr2));
DbgPrint("cr2 %x\n",cr2);
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(;;);
@ -228,9 +231,6 @@ asmlinkage void exception_handler(unsigned int edi,
DbgPrint("ESP %.8x\n",esp);
}
__asm__("movl %%cr2,%0\n\t"
: "=d" (cr2));
DbgPrint("cr2 %x\n",cr2);
if ((cs&0xffff)==KERNEL_CS)
{
@ -241,8 +241,8 @@ asmlinkage void exception_handler(unsigned int edi,
printk("Stack:\n");
for (i=0;i<16;i=i+4)
{
printk("%.8x %.8x %.8x %.8x\n",stack[i],stack[i+1],stack[i+2],
stack[i+3]);
DbgPrint("%.8x %.8x %.8x %.8x\n",stack[i],stack[i+1],stack[i+2],
stack[i+3]);
}
printk("Frames:\n");
for (i=0;i<32;i++)
@ -259,20 +259,20 @@ asmlinkage void exception_handler(unsigned int edi,
sym = j;
}
}
printk(" %.8x (%s+%d)",
stack[i],
symbol_table[sym].name,
stack[i] - symbol_table[sym].value);
DbgPrint(" %.8x (%s+%d)",
stack[i],
symbol_table[sym].name,
stack[i] - symbol_table[sym].value);
}
}
// #endif
}
else
{
printk("SS:ESP %x:%x\n",ss0,esp0);
DbgPrint("SS:ESP %x:%x\n",ss0,esp0);
stack=(unsigned int *)(esp0);
printk("Stack:\n");
DbgPrint("Stack:\n");
for (i=0; i<16; i++)
{
if (MmIsPagePresent(NULL,&stack[i]))

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/halinit.c
* PURPOSE: Initalize the uniprocessor, x86 hal
* PROGRAMMER: David Welch (welch@mcmail.com)
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 11/06/98: Created
*/
@ -20,8 +20,7 @@
/* FUNCTIONS ***************************************************************/
VOID HalInit(boot_param* bp)
{
{
KeInitExceptions();
KeInitIRQ();
KeLowerIrql(DISPATCH_LEVEL);

View file

@ -66,7 +66,6 @@ _idt_descr:
.long _idt
_gdt_descr:
/* .word ((6+128)*8)-1 */
.word ((6+NR_TASKS)*8)-1
.long _gdt

View file

@ -1,7 +1,7 @@
/*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/page.c
* FILE: ntoskrnl/mm/i386/page.c
* PURPOSE: low level memory managment manipulation
* PROGRAMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
@ -28,6 +28,9 @@
#define PA_PRESENT (1<<PA_BIT_PRESENT)
#define PAGETABLE_MAP (0xf0000000)
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
/* FUNCTIONS ***************************************************************/
static ULONG ProtectToPTE(ULONG flProtect)
@ -50,45 +53,53 @@ static ULONG ProtectToPTE(ULONG flProtect)
return(Attributes);
}
PULONG MmGetPageEntry(PEPROCESS Process, PVOID PAddress)
#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
(((ULONG)v / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((ULONG)v / 1024))
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{
ULONG Entry;
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeAttachProcess(Process);
}
Entry = *MmGetPageEntry(Address);
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeDetachProcess();
}
return(Entry);
}
PULONG MmGetPageEntry(PVOID PAddress)
/*
* FUNCTION: Get a pointer to the page table entry for a virtual address
*/
{
ULONG page_table;
PULONG page_tlb;
PULONG page_dir;
ULONG Address = (ULONG)PAddress;
DPRINT("MmGetPageEntry(Process %x, Address %x)\n",Process,Address);
DPRINT("MmGetPageEntry(Address %x)\n", Address);
if (Process != NULL)
page_dir = ADDR_TO_PDE(Address);
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
if ((*page_dir) == 0)
{
page_dir = Process->Pcb.PageTableDirectory;
// (*page_dir) = get_free_page() | (PA_READ | PA_WRITE);
(*page_dir) = get_free_page() | 0x7;
FLUSH_TLB;
}
else
{
page_dir = (PULONG)get_page_directory();
}
DPRINT("page_dir %x\n",page_dir);
page_tlb = (PULONG)physical_to_linear(
PAGE_MASK(page_dir[VADDR_TO_PD_OFFSET(Address)]));
page_tlb = ADDR_TO_PTE(Address);
DPRINT("page_tlb %x\n",page_tlb);
if (PAGE_MASK(page_dir[VADDR_TO_PD_OFFSET(Address)])==0)
{
DPRINT("Creating new page directory\n",0);
page_table = get_free_page(); // Returns a physical address
page_tlb=(PULONG)physical_to_linear(page_table);
memset(page_tlb,0,PAGESIZE);
page_dir[VADDR_TO_PD_OFFSET(Address)]=page_table+0x7;
}
DPRINT("Returning %x\n",page_tlb[VADDR_TO_PT_OFFSET(Address)/4]);
return(&page_tlb[VADDR_TO_PT_OFFSET(Address)/4]);
return(page_tlb);
}
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
{
return((*MmGetPageEntry(Process, Address)) & PA_PRESENT);
return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT);
}
VOID MmSetPage(PEPROCESS Process,
@ -99,10 +110,22 @@ VOID MmSetPage(PEPROCESS Process,
ULONG Attributes = 0;
DPRINT("MmSetPage(Process %x, Address %x, flProtect %x, "
"PhysicalAddress %x)\n",Process,Address,flProtect,
PhysicalAddress);
Attributes = ProtectToPTE(flProtect);
(*MmGetPageEntry(Process, Address)) = PhysicalAddress | Attributes;
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeAttachProcess(Process);
}
(*MmGetPageEntry(Address)) = PhysicalAddress | Attributes;
FLUSH_TLB;
if (Process != NULL && Process != PsGetCurrentProcess())
{
KeDetachProcess();
}
}
VOID MmSetPageProtect(PEPROCESS Process,
@ -113,10 +136,18 @@ VOID MmSetPageProtect(PEPROCESS Process,
PULONG PageEntry;
Attributes = ProtectToPTE(flProtect);
PageEntry = MmGetPageEntry(Process,Address);
if (Process != PsGetCurrentProcess())
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
(*PageEntry) = PAGE_MASK(*PageEntry) | Attributes;
FLUSH_TLB;
if (Process != PsGetCurrentProcess())
{
KeDetachProcess();
}
}
PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
@ -129,7 +160,7 @@ PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
SET_LARGE_INTEGER_HIGH_PART(p, 0);
SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(*MmGetPageEntry(NULL,vaddr)));
SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(*MmGetPageEntry(vaddr)));
return p;
}

View file

@ -24,6 +24,8 @@
/* GLOBALS ***************************************************************/
#define NR_TASKS 128
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
VOID PsBeginThreadWithContextInternal(VOID);
@ -93,7 +95,7 @@ static unsigned int allocate_tss_descriptor(void)
*/
{
unsigned int i;
for (i=0;i<16;i++)
for (i=0;i<NR_TASKS;i++)
{
if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
gdt[FIRST_TSS_OFFSET + i].b==0)
@ -156,13 +158,18 @@ NTSTATUS KeValidateUserContext(PCONTEXT Context)
}
NTSTATUS HalReleaseTask(PETHREAD Thread)
/*
* FUNCTION: Releases the resource allocated for a thread by
* HalInitTaskWithContext or HalInitTask
* NOTE: The thread had better not be running when this is called
*/
{
gdt[Thread->Tcb.Context.nr/8].a=0;
gdt[Thread->Tcb.Context.nr/8].b=0;
ExFreePool(Thread->Tcb.Context.KernelStackBase);
if (Thread->Tcb.Context.SavedKernelStackBase != NULL)
{
ExFreePool(Thread->Tcb.Context.KernelStackBase);
ExFreePool(Thread->Tcb.Context.SavedKernelStackBase);
}
return(STATUS_SUCCESS);
}
@ -227,8 +234,8 @@ NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
Thread->Tcb.Context.cs = KERNEL_CS;
Thread->Tcb.Context.eip = (ULONG)PsBeginThreadWithContextInternal;
Thread->Tcb.Context.io_bitmap[0] = 0xff;
Thread->Tcb.Context.cr3 = (ULONG)MmGetPhysicalAddress(
Thread->ThreadsProcess->Pcb.PageTableDirectory);
Thread->Tcb.Context.cr3 = (ULONG)
Thread->ThreadsProcess->Pcb.PageTableDirectory;
Thread->Tcb.Context.ds = KERNEL_DS;
Thread->Tcb.Context.es = KERNEL_DS;
Thread->Tcb.Context.fs = KERNEL_DS;
@ -242,7 +249,7 @@ NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
return(STATUS_SUCCESS);
}
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
/*
* FUNCTION: Initializes the HAL portion of a thread object
* ARGUMENTS:
@ -252,7 +259,7 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
* RETURNS: True if the function succeeded
*/
{
unsigned int desc = allocate_tss_descriptor();
unsigned int desc;
unsigned int length = sizeof(hal_thread_state) - 1;
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
PULONG kernel_stack = ExAllocatePool(NonPagedPool,4096);
@ -266,6 +273,12 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
*/
assert(sizeof(hal_thread_state)>=0x68);
desc = allocate_tss_descriptor();
if (desc == 0)
{
return(STATUS_UNSUCCESSFUL);
}
/*
* Setup a TSS descriptor
*/
@ -302,8 +315,8 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
thread->Tcb.Context.cs = KERNEL_CS;
thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
thread->Tcb.Context.io_bitmap[0] = 0xff;
thread->Tcb.Context.cr3 =
MmGetPhysicalAddress(thread->ThreadsProcess->Pcb.PageTableDirectory);
thread->Tcb.Context.cr3 = (ULONG)
thread->ThreadsProcess->Pcb.PageTableDirectory;
thread->Tcb.Context.ds = KERNEL_DS;
thread->Tcb.Context.es = KERNEL_DS;
thread->Tcb.Context.fs = KERNEL_DS;
@ -314,8 +327,7 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
thread->Tcb.Context.SavedKernelStackBase = NULL;
DPRINT("Allocated %x\n",desc*8);
return(TRUE);
return(STATUS_SUCCESS);
}
void HalInitFirstTask(PETHREAD thread)

View file

@ -1,8 +1,8 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
* PURPOSE: Graceful system shutdown if a bug is detected
* FILE: ntoskrnl/ke/ldt.c
* PURPOSE: LDT managment
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
* PURPOSE: Initalizes the kernel
* PROGRAMMER: David Welch (welch@mcmail.com)
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 28/05/98: Created
*/
@ -105,6 +105,7 @@ void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,
extern int edata;
extern int end;
asmlinkage void _main(boot_param* _bp)
/*
* FUNCTION: Called by the boot loader to start the kernel
@ -173,7 +174,8 @@ asmlinkage void _main(boot_param* _bp)
* Load Auto configured drivers
*/
LdrLoadAutoConfigDrivers();
/*
* Launch initial process
*/

View file

@ -0,0 +1,78 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c
* PURPOSE: Microkernel process management
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/mm.h>
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
VOID KeAttachProcess(PEPROCESS Process)
{
KIRQL oldlvl;
PETHREAD CurrentThread;
ULONG PageDir;
DPRINT("KeAttachProcess(Process %x)\n",Process);
CurrentThread = PsGetCurrentThread();
if (CurrentThread->OldProcess != NULL)
{
DbgPrint("Invalid attach (thread is already attached)\n");
KeBugCheck(0);
}
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
CurrentThread->OldProcess = PsGetCurrentProcess();
CurrentThread->ThreadsProcess = Process;
PageDir = (ULONG)CurrentThread->ThreadsProcess->Pcb.PageTableDirectory;
CurrentThread->Tcb.Context.cr3 = PageDir;
__asm__("movl %0,%%cr3\n\t"
: /* no inputs */
: "r" (PageDir));
KeLowerIrql(oldlvl);
}
VOID KeDetachProcess(VOID)
{
KIRQL oldlvl;
PETHREAD CurrentThread;
ULONG PageDir;
DPRINT("KeDetachProcess()\n");
CurrentThread = PsGetCurrentThread();
if (CurrentThread->OldProcess == NULL)
{
DbgPrint("Invalid detach (thread was not attached)\n");
KeBugCheck(0);
}
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
CurrentThread->ThreadsProcess = CurrentThread->OldProcess;
CurrentThread->OldProcess = NULL;
PageDir = (ULONG)CurrentThread->ThreadsProcess->Pcb.PageTableDirectory;
CurrentThread->Tcb.Context.cr3 = PageDir;
__asm__("movl %0,%%cr3\n\t"
: /* no inputs */
: "r" (PageDir));
KeLowerIrql(oldlvl);
}

View file

@ -24,7 +24,7 @@ VOID KeInitializeSemaphore(PKSEMAPHORE Semaphore,
KeInitializeDispatcherHeader(&Semaphore->Header,SemaphoreType,
sizeof(KSEMAPHORE)/sizeof(ULONG),
Count);
Semaphore->Limit=Limit;
Semaphore->Limit = Limit;
}
LONG KeReadStateSemaphore(PKSEMAPHORE Semaphore)
@ -37,23 +37,26 @@ LONG KeReleaseSemaphore(PKSEMAPHORE Semaphore,
LONG Adjustment,
BOOLEAN Wait)
{
long initState=Semaphore->Header.SignalState;
if(Semaphore->Limit < initState+Adjustment
ULONG initState = Semaphore->Header.SignalState;
KeAcquireDispatcherDatabaseLock(Wait);
if(Semaphore->Limit < initState+Adjustment
|| initState > initState+Adjustment)
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
Semaphore->Header.SignalState+=Adjustment;
if((initState == 0)
&& (Semaphore->Header.WaitListHead.Flink != &Semaphore->Header.WaitListHead))
{
// wake up SignalState waiters
while(Semaphore->Header.SignalState > 0
&& KeDispatcherObjectWakeOne(Semaphore->Header) ) ;
}
if (Wait)
{
// FIXME(2) : in this case, we must store somewhere that we have been here
// and the functions KeWaitxxx must take care of this
}
return initState;
{
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
}
Semaphore->Header.SignalState += Adjustment;
if (initState == 0)
{
// wake up SignalState waiters
while(Semaphore->Header.SignalState > 0
&& KeDispatcherObjectWake(&Semaphore->Header)) ;
}
KeReleaseDispatcherDatabaseLock(Wait);
return initState;
}

View file

@ -48,7 +48,7 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait)
* PURPOSE: Acquires the dispatcher database lock for the caller
*/
{
DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait);
// DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait);
if (WaitSet && Owner == KeGetCurrentThread())
{
return;
@ -60,7 +60,7 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait)
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
{
DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x)\n",Wait);
// DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x)\n",Wait);
assert(Wait==WaitSet);
if (!Wait)
{
@ -69,11 +69,16 @@ VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
}
}
VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
{
PKWAIT_BLOCK current;
PLIST_ENTRY current_entry;
if (IsListEmpty(&hdr->WaitListHead))
{
return(FALSE);
}
while (!IsListEmpty(&(hdr->WaitListHead)))
{
current_entry = RemoveHeadList(&hdr->WaitListHead);
@ -82,9 +87,10 @@ VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
DPRINT("Waking %x\n",current->Thread);
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
};
return(TRUE);
}
BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
{
PKWAIT_BLOCK current;
PLIST_ENTRY current_entry;
@ -101,29 +107,48 @@ BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
WaitListEntry);
DPRINT("current_entry %x current %x\n",current_entry,current);
DPRINT("Waking %x\n",current->Thread);
if (hdr->Type == SemaphoreType)
hdr->SignalState--;
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
return(TRUE);
}
VOID KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
/*
* FUNCTION: Wake threads waiting on a dispatcher object
* NOTE: The exact semantics of waking are dependant on the type of object
*/
{
BOOL Ret;
DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr);
// DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n",
// &hdr->WaitListHead,hdr->WaitListHead.Flink);
if (hdr->Type==NotificationEvent)
switch (hdr->Type)
{
KeDispatcherObjectWakeAll(hdr);
}
if (hdr->Type==SynchronizationEvent)
{
if (KeDispatcherObjectWakeOne(hdr))
{
hdr->SignalState=FALSE;
}
case NotificationEvent:
return(KeDispatcherObjectWakeAll(hdr));
case SynchronizationEvent:
Ret = KeDispatcherObjectWakeOne(hdr);
if (Ret)
{
hdr->SignalState = FALSE;
}
return(Ret);
case SemaphoreType:
Ret = KeDispatcherObjectWakeOne(hdr);
if (Ret)
{
hdr->SignalState--;
}
return(Ret);
case ProcessType:
return(KeDispatcherObjectWakeAll(hdr));
}
DbgPrint("Dispatcher object has unknown type\n");
KeBugCheck(0);
return(FALSE);
}
@ -149,20 +174,25 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object;
KWAIT_BLOCK blk;
DPRINT("Entering KeWaitForSingleObject(Object %x)\n",Object);
// FIXME : if KeReleaseSemaphore called with wait just before KeWaitxxx
// we must do something special.
DPRINT("Entering KeWaitForSingleObject(Object %x) "
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
KeAcquireDispatcherDatabaseLock(FALSE);
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
if (hdr->SignalState > 0)
{
if (hdr->Type == SynchronizationEvent)
{
hdr->SignalState=FALSE;
}
else if (hdr->Type == SemaphoreType)
hdr->SignalState--;
switch (hdr->Type)
{
case SynchronizationEvent:
hdr->SignalState = FALSE;
break;
case SemaphoreType:
hdr->SignalState--;
break;
}
KeReleaseDispatcherDatabaseLock(FALSE);
return(STATUS_SUCCESS);
}
@ -187,6 +217,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
{
KeCancelTimer(&KeGetCurrentThread()->TimerBlock);
}
DPRINT("Returning from KeWaitForSingleObject()\n");
return(STATUS_SUCCESS);
}

View file

@ -17,7 +17,8 @@ RTL_OBJECTS = rtl/vsprintf.o rtl/lookas.o rtl/unicode.o rtl/strtok.o \
KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o ke/exports.o \
ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \
ke/sem.o ke/critical.o ke/event.o ke/apc.o ke/bug.o \
ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o
ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o \
ke/process.o
MM_OBJECTS = mm/mm.o mm/freelist.o mm/pool.o mm/virtual.o \
mm/mdl.o mm/zone.o mm/special.o mm/paging.o \

View file

@ -417,6 +417,13 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
1);
}
}
for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++)
{
MmSetPage(NULL,
MemoryArea->BaseAddress + (i*PAGESIZE),
0,
0);
}
RemoveEntryList(&(MemoryArea->Entry));
ExFreePool(MemoryArea);

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mdl.c
* PURPOSE: Manipulates MDLs
* PROGRAMMER: David Welch (welch@mcmail.com)
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 27/05/98: Created
*/

View file

@ -58,6 +58,8 @@ void MmInitialize(boot_param* bp)
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());
DPRINT("InitalizeMM()\n");
@ -65,7 +67,7 @@ void MmInitialize(boot_param* bp)
/*
* Unmap low memory
*/
(get_page_directory())[0]=0;
page_directory[0]=0;
FLUSH_TLB;
CHECKPOINT;
@ -122,12 +124,8 @@ void MmInitialize(boot_param* bp)
PAGE_NOACCESS,
0);
}
MmSetPage(NULL,
0,
PAGE_NOACCESS,
0);
FLUSH_TLB;
CHECKPOINT;
/*
* Intialize memory areas
*/

View file

@ -79,15 +79,41 @@ ULONG EiNrUsedBlocks = 0;
* If set then the page is used by a kmalloc block
*/
static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,};
static KSPIN_LOCK AllocMapLock;
unsigned int EiFreeNonPagedPool = 0;
unsigned int EiUsedNonPagedPool = 0;
/* FUNCTIONS ***************************************************************/
PVOID ExAllocatePage(VOID)
{
KIRQL oldlvl;
ULONG addr;
ULONG i;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i=1; i<ALLOC_MAP_SIZE;i++)
{
if (!test_bit(i%32,&alloc_map[i/32]))
{
addr = kernel_pool_base + (i*PAGESIZE);
MmSetPage(NULL,
(PVOID)addr,
PAGE_READWRITE,
get_free_page());
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return((PVOID)addr);
}
}
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return(NULL);
}
VOID ExInitNonPagedPool(ULONG BaseAddress)
{
kernel_pool_base=BaseAddress;
kernel_pool_base = BaseAddress;
KeInitializeSpinLock(&AllocMapLock);
}
#if 0

View file

@ -18,6 +18,8 @@
#include <internal/ob.h>
#include <internal/io.h>
#include <internal/ps.h>
#include <string.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
@ -106,7 +108,7 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
IO_STATUS_BLOCK IoStatus;
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
MemoryArea,Address);
MmSetPage(NULL,
Address,
@ -150,18 +152,19 @@ asmlinkage int page_fault_handler(unsigned int cs,
*/
unsigned int cr2;
__asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
DPRINT("Page fault at address %x with eip %x\n",cr2,eip);
DPRINT("Page fault at address %x with eip %x in process %x\n",cr2,eip,
PsGetCurrentProcess());
cr2 = PAGE_ROUND_DOWN(cr2);
if (KeGetCurrentIrql()!=PASSIVE_LEVEL)
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
{
DbgPrint("Page fault at high IRQL\n");
return(0);
// KeBugCheck(0);
}
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
/*
* Find the memory area for the faulting address
@ -171,7 +174,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
/*
* Check permissions
*/
if (cs!=KERNEL_CS)
if (cs != KERNEL_CS)
{
printk("%s:%d\n",__FILE__,__LINE__);
return(0);
@ -184,7 +187,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
}
MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2);
if (MemoryArea==NULL)
if (MemoryArea == NULL)
{
printk("%s:%d\n",__FILE__,__LINE__);
return(0);
@ -199,7 +202,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
case MEMORY_AREA_SECTION_VIEW_COMMIT:
if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
{
stat=1;
stat = 1;
}
else
{
@ -631,6 +634,16 @@ NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,
NumberOfBytesRead));
}
NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead)
{
UNIMPLEMENTED;
}
#if 0
NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
@ -678,6 +691,7 @@ NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
}
return(STATUS_SUCCESS);
}
#endif
NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,
PVOID BaseAddress,
@ -717,11 +731,10 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten)
{
PEPROCESS Process;
PMEMORY_AREA OutMemoryArea;
ULONG i;
NTSTATUS Status;
PULONG CurrentEntry;
PMDL Mdl;
PVOID SystemAddress;
PEPROCESS Process;
DPRINT("ZwWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
"Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
@ -737,56 +750,22 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
{
return(Status);
}
OutMemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
if (OutMemoryArea == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
Mdl = MmCreateMdl(NULL,
Buffer,
NumberOfBytesToWrite);
MmProbeAndLockPages(Mdl,
UserMode,
IoReadAccess);
KeAttachProcess(Process);
SystemAddress = MmGetSystemAddressForMdl(Mdl);
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
KeDetachProcess();
*NumberOfBytesWritten = NumberOfBytesToWrite;
DPRINT("*Buffer %x\n",((PULONG)Buffer)[0]);
for (i=0; i<(PAGE_ROUND_DOWN(NumberOfBytesToWrite)/PAGESIZE); i++)
{
if (!MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))
{
DPRINT("OutMemoryArea->Attributes %x\n",
OutMemoryArea->Attributes);
MmSetPage(Process,
BaseAddress + (i*PAGESIZE),
OutMemoryArea->Attributes,
get_free_page());
}
CurrentEntry = MmGetPageEntry(Process,
(PVOID)((DWORD)BaseAddress +
(i*PAGESIZE)));
RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)) +
(((DWORD)BaseAddress)%PAGESIZE),
Buffer + (i*PAGESIZE),
PAGESIZE);
}
if ((NumberOfBytesToWrite % PAGESIZE) != 0)
{
if (!MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))
{
MmSetPage(Process,
BaseAddress + (i*PAGESIZE),
OutMemoryArea->Attributes,
get_free_page());
}
CurrentEntry = MmGetPageEntry(Process,
BaseAddress + (i*PAGESIZE));
DPRINT("addr %x\n",
physical_to_linear(PAGE_MASK(*CurrentEntry)) +
(((DWORD)BaseAddress)%PAGESIZE));
RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)) +
(((DWORD)BaseAddress)%PAGESIZE),
Buffer + (i*PAGESIZE),
NumberOfBytesToWrite % PAGESIZE);
}
return(STATUS_SUCCESS);
}

View file

@ -80,7 +80,7 @@ NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
PiTerminateProcessThreads(Process, ExitStatus);
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader);
KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
if (PsGetCurrentThread()->ThreadsProcess == Process)
{

View file

@ -163,6 +163,7 @@ NTSTATUS STDCALL ZwCreateProcess(
ULONG i;
PKPROCESS KProcess;
NTSTATUS Status;
PULONG PhysicalPageDirectory;
DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
@ -184,7 +185,7 @@ NTSTATUS STDCALL ZwCreateProcess(
ObjectAttributes,
PsProcessType);
KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
0,
ProcessType,
sizeof(EPROCESS),
FALSE);
KProcess = &(Process->Pcb);
@ -194,16 +195,20 @@ NTSTATUS STDCALL ZwCreateProcess(
InheritObjectTable,
Process);
PageDirectory = (PULONG)physical_to_linear((ULONG)get_free_page());
KProcess->PageTableDirectory = PageDirectory;
PhysicalPageDirectory = (PULONG)get_free_page();
PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory);
KProcess->PageTableDirectory = PhysicalPageDirectory;
CurrentPageDirectory = (PULONG)get_page_directory();
CurrentPageDirectory = (PULONG)physical_to_linear(
(ULONG)get_page_directory());
memset(PageDirectory,0,PAGESIZE);
for (i=768;i<1024;i++)
for (i=768; i<896; i++)
{
PageDirectory[i]=CurrentPageDirectory[i];
PageDirectory[i] = CurrentPageDirectory[i];
}
PageDirectory[0xf0000000 / (4*1024*1024)]
= (ULONG)PhysicalPageDirectory | 0x7;
/*
* FIXME: I don't what I'm supposed to know with a section handle

View file

@ -273,12 +273,8 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
VOID PsResumeThread(PETHREAD Thread)
{
DPRINT("PsResumeThread(Thread %x)\n",Thread);
Thread->Tcb.SuspendCount--;
DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount);
DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n",
Thread->Tcb.ThreadState,THREAD_STATE_RUNNING);
if (Thread->Tcb.SuspendCount <= 0 &&
if (Thread->Tcb.SuspendCount <= 0 &&
Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)
{
DPRINT("Setting thread to runnable\n");
@ -386,12 +382,16 @@ NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,
Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
DesiredAccess,ObjectAttributes);
if (Status != STATUS_SUCCESS)
if (!NT_SUCCESS(Status))
{
return(Status);
}
HalInitTaskWithContext(Thread,ThreadContext);
Status = HalInitTaskWithContext(Thread,ThreadContext);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Thread->StartAddress=NULL;
if (Client!=NULL)
@ -440,13 +440,17 @@ NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,
Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
DesiredAccess,ObjectAttributes);
if (Status != STATUS_SUCCESS)
if (!NT_SUCCESS(Status))
{
return(Status);
}
Thread->StartAddress=StartRoutine;
HalInitTask(Thread,StartRoutine,StartContext);
Status = HalInitTask(Thread,StartRoutine,StartContext);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ClientId!=NULL)
{