#endif
// === IMPORTS ===
+extern void _UsertextEnd, _UsertextBase;
extern Uint32 gaInitPageDir[1024];
extern Uint32 gaInitPageTable[1024];
extern void Threads_SegFault(tVAddr Addr);
memset( &gaPageTable[i*1024], 0, 0x1000 );
}
#endif
+
+ // Unset kernel on the User Text pages
+ for( i = ((tVAddr)&_UsertextEnd-(tVAddr)&_UsertextBase+0xFFF)/4096; i--; ) {
+ Log("MM_SetFlags( 0x%08x, 0, MM_PFLAG_KERNEL)", (tVAddr)&_UsertextBase + i*4096);
+ MM_SetFlags( (tVAddr)&_UsertextBase + i*4096, 0, MM_PFLAG_KERNEL );
+ }
}
/**
// Read-Only
if( Mask & MM_PFLAG_RO )
{
- if( Flags & MM_PFLAG_RO ) *ent &= ~PF_WRITE;
- else *ent |= PF_WRITE;
+ if( Flags & MM_PFLAG_RO ) {
+ *ent &= ~PF_WRITE;
+ }
+ else {
+ gaPageDir[VAddr >> 22] |= PF_WRITE;
+ *ent |= PF_WRITE;
+ }
}
// Kernel
if( Mask & MM_PFLAG_KERNEL )
{
- if( Flags & MM_PFLAG_KERNEL ) *ent &= ~PF_USER;
- else *ent |= PF_USER;
+ if( Flags & MM_PFLAG_KERNEL ) {
+ *ent &= ~PF_USER;
+ }
+ else {
+ gaPageDir[VAddr >> 22] |= PF_USER;
+ *ent |= PF_USER;
+ }
}
// Copy-On-Write
*ent |= PF_WRITE;
}
}
+
+ //Log("MM_SetFlags: *ent = 0x%08x, gaPageDir[%i] = 0x%08x",
+ // *ent, VAddr >> 22, gaPageDir[VAddr >> 22]);
}
/**
--- /dev/null
+; AcessOS Microkernel Version
+; Start.asm
+
+[bits 32]
+
+KERNEL_BASE equ 0xC0000000
+
+KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
+
+[section .text]
+; --------------
+; Task Scheduler
+; --------------
+[extern Proc_Scheduler]
+[global SchedulerBase]
+SchedulerBase:
+ pusha
+ push ds
+ push es
+ push fs
+ push gs
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov eax, [esp+12*4] ; CPU Number
+ push eax ; Pus as argument
+
+ call Proc_Scheduler
+
+ add esp, 4 ; Remove Argument
+
+ pop gs
+ pop fs
+ pop es
+ pop ds
+
+ mov dx, 0x20
+ mov al, 0x20
+ out dx, al ; ACK IRQ
+ popa
+ add esp, 4 ; CPU ID
+ ; No Error code / int num
+ iret
+
+[extern Proc_Clone]
+[extern Threads_Exit]
+[global SpawnTask]
+SpawnTask:
+ ; Call Proc_Clone with Flags=0
+ xor eax, eax
+ push eax
+ push eax
+ call Proc_Clone
+ add esp, 8 ; Remove arguments from stack
+
+ test eax, eax
+ jnz .parent
+
+ ; In child, so now set up stack frame
+ mov ebx, [esp+4] ; Child Function
+ mov edx, [esp+8] ; Argument
+ ; Child
+ push edx ; Argument
+ call ebx ; Function
+ call Threads_Exit ; Kill Thread
+
+.parent:
+ ret
+
+;
+; Calls a user fault handler
+;
+[global Proc_AlterUserReturnAddr]
+[extern Proc_GetCurThread]
+Proc_AlterUserReturnAddr:
+ ; EBP is the handler to use
+
+ call Proc_GetCurThread
+ xchg bx, bx
+
+ ; EAX is the current thread
+ mov ebx, eax
+ mov eax, [ebx+40] ; Get Kernel Stack
+ sub eax, KSTACK_USERSTATE_SIZE
+
+ ;
+ ; NOTE: This can cause corruption if the signal happens while the user
+ ; has called a kernel operation.
+ ; Good thing this can only be called on a user fault.
+ ;
+
+ ; Get and alter User SP
+ mov ecx, [eax+KSTACK_USERSTATE_SIZE-12]
+ mov edx, [ebx+60] ; Get Signal Number
+ mov [ecx-4], edx
+ mov [ecx-8], DWORD User_Syscall_RetAndExit
+ sub ecx, 8
+
+ ; Restore Segment Registers
+ mov ax, 0x23
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ push 0x23 ; SS
+ push ecx ; ESP
+ push 0x22 ; EFLAGS
+ push 0x1B ; CS
+ push ebp ; EIP
+
+ iret
+
+
+[section .usertext]
+User_Syscall_RetAndExit:
+ push eax
+ call User_Syscall_Exit
+User_Syscall_Exit:
+ xor eax, eax
+ mov ebx, [esp+4]
+ int 0xAC