From: John Hodge Date: Fri, 23 Apr 2010 13:24:35 +0000 (+0800) Subject: Fixes to error handling and User text mappings X-Git-Tag: rel0.06~222 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=7a6a1cbc62289d64d604fb2cb204d21659c4905e;p=tpg%2Facess2.git Fixes to error handling and User text mappings --- diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index ce0a54c7..6b06f1ca 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 2027 +BUILD_NUM = 2035 diff --git a/Kernel/arch/x86/link.ld b/Kernel/arch/x86/link.ld index 2fe17641..75b712fb 100644 --- a/Kernel/arch/x86/link.ld +++ b/Kernel/arch/x86/link.ld @@ -24,6 +24,7 @@ SECTIONS { _UsertextBase = .; *(.usertext) } + _UsertextEnd = .; .rodata ALIGN(0x1000): AT(ADDR(.rodata) - 0xC0000000) { *(.initpd) diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index f2be750f..f3cd7bb7 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -66,6 +66,7 @@ typedef Uint32 tTabEnt; #endif // === IMPORTS === +extern void _UsertextEnd, _UsertextBase; extern Uint32 gaInitPageDir[1024]; extern Uint32 gaInitPageTable[1024]; extern void Threads_SegFault(tVAddr Addr); @@ -153,6 +154,12 @@ void MM_InstallVirtual() 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 ); + } } /** @@ -781,15 +788,25 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) // 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 @@ -804,6 +821,9 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) *ent |= PF_WRITE; } } + + //Log("MM_SetFlags: *ent = 0x%08x, gaPageDir[%i] = 0x%08x", + // *ent, VAddr >> 22, gaPageDir[VAddr >> 22]); } /** diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm new file mode 100644 index 00000000..9d752bf1 --- /dev/null +++ b/Kernel/arch/x86/proc.asm @@ -0,0 +1,126 @@ +; 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