Fixes to error handling and User text mappings
authorJohn Hodge <[email protected]>
Fri, 23 Apr 2010 13:24:35 +0000 (21:24 +0800)
committerJohn Hodge <[email protected]>
Fri, 23 Apr 2010 13:24:35 +0000 (21:24 +0800)
Kernel/Makefile.BuildNum
Kernel/arch/x86/link.ld
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.asm [new file with mode: 0644]

index ce0a54c..6b06f1c 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 2027
+BUILD_NUM = 2035
index 2fe1764..75b712f 100644 (file)
@@ -24,6 +24,7 @@ SECTIONS {
                _UsertextBase = .;
                *(.usertext)
        }
+       _UsertextEnd = .;
        
        .rodata ALIGN(0x1000): AT(ADDR(.rodata) - 0xC0000000) {
                *(.initpd)
index f2be750..f3cd7bb 100644 (file)
@@ -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 (file)
index 0000000..9d752bf
--- /dev/null
@@ -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

UCC git Repository :: git.ucc.asn.au