; EAX is the current thread
mov ebx, eax
mov eax, [ebx+40] ; Get Kernel Stack
- sub eax, KSTACK_USERSTATE_SIZE
+ sub eax, KSTACK_USERSTATE_SIZE
;
; NOTE: This can cause corruption if the signal happens while the user
; Good thing this can only be called on a user fault.
;
+ ; Validate user ESP
+ ; - Page Table
+ mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
+ %if USE_PAE
+ %error PAE Support
+ %else
+ mov ecx, edx
+ shr ecx, 22
+ test BYTE [0xFC3F0000+ecx*4], 1
+ jnz .justKillIt
+ %endif
+ ; - Page
+ mov ecx, edx
+ shr ecx, 12
+ test BYTE [0xFC000000+ecx*4], 1
+ jnz .justKillIt
+ ; Adjust
+ sub edx, 8
+ ; - Page Table
+ %if USE_PAE
+ %else
+ mov ecx, edx
+ shr ecx, 22
+ test BYTE [0xFC3F0000+ecx*4], 1
+ jnz .justKillIt
+ %endif
+ ; - Page
+ mov ecx, edx
+ shr ecx, 12
+ test BYTE [0xFC000000+ecx*4], 1
+ jnz .justKillIt
+
; 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
+ mov ecx, edx
+ mov edx, [ebx+60] ; Get Signal Number from TCB
+ mov [ecx+4], edx ; Parameter (Signal/Error Number)
+ mov [ecx], DWORD User_Syscall_RetAndExit ; Return Address
; Restore Segment Registers
mov ax, 0x23
push ebp ; EIP
iret
+
+ ; Just kill the bleeding thing
+ ; (I know it calls int 0xAC in kernel mode, but meh)
+.justKillIt:
+ xor eax, eax
+ xor ebx, ebx
+ dec ebx
+ int 0xAC
[global GetCPUNum]
GetCPUNum:
shr ax, 3 ; ax /= 8
ret
+; Usermode code exported by the kernel
[section .usertext]
User_Syscall_RetAndExit:
push eax
-; AcessOS Microkernel Version\r
-; Start.asm\r
-\r
-[bits 32]\r
-\r
-KERNEL_BASE equ 0xC0000000\r
-\r
-[extern __load_addr]\r
-[extern __bss_start]\r
-[extern gKernelEnd]\r
-[section .multiboot]\r
-mboot:\r
- ; Multiboot macros to make a few lines later more readable\r
- MULTIBOOT_PAGE_ALIGN equ 1<<0\r
- MULTIBOOT_MEMORY_INFO equ 1<<1\r
- MULTIBOOT_HEADER_MAGIC equ 0x1BADB002\r
- MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO\r
- MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)\r
- \r
- ; This is the GRUB Multiboot header. A boot signature\r
- dd MULTIBOOT_HEADER_MAGIC\r
- dd MULTIBOOT_HEADER_FLAGS\r
- dd MULTIBOOT_CHECKSUM\r
- dd mboot - KERNEL_BASE ;Location of Multiboot Header\r
- \r
-; Multiboot 2 Header\r
-mboot2:\r
- MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6\r
- MULTIBOOT2_HEADER_ARCH equ 0\r
- MULTIBOOT2_HEADER_LENGTH equ (mboot2_end-mboot2)\r
- MULTIBOOT2_CHECKSUM equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH)\r
- \r
- dd MULTIBOOT2_HEADER_MAGIC\r
- dd MULTIBOOT2_HEADER_ARCH\r
- dd MULTIBOOT2_HEADER_LENGTH\r
- dd MULTIBOOT2_CHECKSUM\r
- ; MBoot2 Address Header\r
- dw 2, 0\r
- dd 8 + 16\r
- dd mboot2 ; Location of Multiboot Header\r
- dd __load_addr - KERNEL_BASE ; Kernel Load base\r
- dd __bss_start - KERNEL_BASE ; Kernel Data End\r
- dd gKernelEnd - KERNEL_BASE ; Kernel BSS End\r
- ; MBoot2 Entry Point Tag\r
- dw 3, 0\r
- dd 8 + 4\r
- dd start - KERNEL_BASE\r
- ; MBoot2 Module Alignment Tag\r
- dw 6, 0\r
- dd 12 ; ???\r
- dd 0 ; Search me, seems it wants padding\r
- ; Terminator\r
- dw 0, 0\r
- dd 8\r
-mboot2_end:\r
- \r
-[section .text]\r
-[extern kmain]\r
-[global start]\r
-start:\r
- ; Set up stack\r
- mov esp, Kernel_Stack_Top\r
- \r
- ; Start Paging\r
- mov ecx, gaInitPageDir - KERNEL_BASE\r
- mov cr3, ecx\r
- \r
- mov ecx, cr0\r
- or ecx, 0x80010000 ; PG and WP\r
- mov cr0, ecx\r
- \r
- lea ecx, [.higherHalf]\r
- jmp ecx\r
-.higherHalf:\r
-\r
- ; Call the kernel\r
- push ebx ; Multiboot Info\r
- push eax ; Multiboot Magic Value\r
+; AcessOS Microkernel Version
+; Start.asm
+
+[bits 32]
+
+KERNEL_BASE equ 0xC0000000
+
+[extern __load_addr]
+[extern __bss_start]
+[extern gKernelEnd]
+[section .multiboot]
+mboot:
+ ; Multiboot macros to make a few lines later more readable
+ MULTIBOOT_PAGE_ALIGN equ 1<<0
+ MULTIBOOT_MEMORY_INFO equ 1<<1
+ MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
+ MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
+ MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+
+ ; This is the GRUB Multiboot header. A boot signature
+ dd MULTIBOOT_HEADER_MAGIC
+ dd MULTIBOOT_HEADER_FLAGS
+ dd MULTIBOOT_CHECKSUM
+ dd mboot - KERNEL_BASE ;Location of Multiboot Header
+
+; Multiboot 2 Header
+;mboot2:
+; MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6
+; MULTIBOOT2_HEADER_ARCH equ 0
+; MULTIBOOT2_HEADER_LENGTH equ (mboot2_end-mboot2)
+; MULTIBOOT2_CHECKSUM equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH)
+;
+; dd MULTIBOOT2_HEADER_MAGIC
+; dd MULTIBOOT2_HEADER_ARCH
+; dd MULTIBOOT2_HEADER_LENGTH
+; dd MULTIBOOT2_CHECKSUM
+; ; MBoot2 Address Header
+; dw 2, 0
+; dd 8 + 16
+; dd mboot2 ; Location of Multiboot Header
+; dd __load_addr - KERNEL_BASE ; Kernel Load base
+; dd __bss_start - KERNEL_BASE ; Kernel Data End
+; dd gKernelEnd - KERNEL_BASE ; Kernel BSS End
+; ; MBoot2 Entry Point Tag
+; dw 3, 0
+; dd 8 + 4
+; dd start - KERNEL_BASE
+; ; MBoot2 Module Alignment Tag
+; dw 6, 0
+; dd 12 ; ???
+; dd 0 ; Search me, seems it wants padding
+; ; Terminator
+; dw 0, 0
+; dd 8
+;mboot2_end:
+
+[section .text]
+[extern kmain]
+[global start]
+start:
+
+ ; Set up stack
+ mov esp, Kernel_Stack_Top
+
+ ; Start Paging
+ mov ecx, gaInitPageDir - KERNEL_BASE
+ mov cr3, ecx
+
+ mov ecx, cr0
+ or ecx, 0x80010000 ; PG and WP
+ mov cr0, ecx
+
+ lea ecx, [.higherHalf]
+ jmp ecx
+.higherHalf:
+
+ ; Call the kernel
+ push ebx ; Multiboot Info
+ push eax ; Multiboot Magic Value
call kmain
- ; Halt the Machine\r
- cli\r
-.hlt:\r
- hlt\r
- jmp .hlt\r
-\r
-; \r
-; Multiprocessing AP Startup Code (Must be within 0x10FFF0)\r
-;\r
-%if USE_MP\r
-[extern gGDT]\r
-[extern gGDTPtr]\r
-[extern gIDTPtr]\r
-[extern gpMP_LocalAPIC]\r
-[extern gaAPIC_to_CPU]\r
-[extern gaCPUs]\r
-[extern giNumInitingCPUs]\r
-lGDTPtr: ; Local GDT Pointer\r
- dw 2*8-1\r
- dd gGDT-KERNEL_BASE\r
-\r
-[bits 16]\r
-[global APStartup]\r
-APStartup:\r
- xchg bx, bx ; MAGIC BREAK!\r
- mov ax, 0xFFFF\r
- mov ds, ax\r
- lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]\r
- mov eax, cr0\r
- or al, 1\r
- mov cr0, eax\r
- jmp 08h:DWORD .ProtectedMode-KERNEL_BASE\r
-[bits 32]\r
-.ProtectedMode:\r
- ; Start Paging\r
- mov eax, gaInitPageDir - KERNEL_BASE\r
- mov cr3, eax\r
- mov eax, cr0\r
- or eax, 0x80010000 ; PG and WP\r
- mov cr0, eax\r
- ; Jump to higher half\r
- lea eax, [.higherHalf]\r
- jmp eax\r
-.higherHalf:\r
- ; Load True GDT & IDT\r
- lgdt [gGDTPtr]\r
- lidt [gIDTPtr]\r
-\r
- mov eax, [gpMP_LocalAPIC]\r
- mov DWORD [eax], 0\r
- xor ecx, ecx\r
- mov cl, BYTE [eax+0x10]\r
- ; CL is now local APIC ID\r
- mov cl, BYTE [gaAPIC_to_CPU+ecx]\r
- ; CL is now the CPU ID\r
- mov BYTE [gaCPUs+ecx*8+1], 1\r
- ; Decrement the remaining CPU count\r
- dec DWORD [giNumInitingCPUs]\r
- ; CPU is now marked as initialised\r
- sti\r
-.hlt:\r
- hlt\r
- jmp .hlt\r
-%endif\r
-\r
-[global GetEIP]\r
-GetEIP:\r
- mov eax, [esp]\r
- ret\r
-\r
-; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)\r
-; Call a function passing the array as arguments\r
-[global CallWithArgArray]\r
-CallWithArgArray:\r
- push ebp\r
- mov ebp, esp\r
- mov ecx, [ebp+12] ; Get NArgs\r
- mov edx, [ebp+16]\r
-\r
-.top:\r
- mov eax, [edx+ecx*4-4]\r
- push eax\r
- loop .top\r
- \r
- mov eax, [ebp+8]\r
- call eax\r
- lea esp, [ebp]\r
- pop ebp\r
- ret\r
-\r
-[section .initpd]\r
-[global gaInitPageDir]\r
-[global gaInitPageTable]\r
-align 0x1000\r
-gaInitPageDir:\r
- dd gaInitPageTable-KERNEL_BASE+3 ; 0x00\r
- times 1024-256-1 dd 0\r
- dd gaInitPageTable-KERNEL_BASE+3 ; 0xC0\r
- times 256-1 dd 0\r
-align 0x1000\r
-gaInitPageTable:\r
- %assign i 0\r
- %rep 1024\r
- dd i*0x1000+3\r
- %assign i i+1\r
- %endrep\r
-[global Kernel_Stack_Top]\r
-ALIGN 0x1000\r
- times 1024 dd 0\r
-Kernel_Stack_Top:\r
+ ; Halt the Machine
+ cli
+.hlt:
+ hlt
+ jmp .hlt
+
+;
+; Multiprocessing AP Startup Code (Must be within 0x10FFF0)
+;
+%if USE_MP
+[extern gGDT]
+[extern gGDTPtr]
+[extern gIDTPtr]
+[extern gpMP_LocalAPIC]
+[extern gaAPIC_to_CPU]
+[extern gaCPUs]
+[extern giNumInitingCPUs]
+lGDTPtr: ; Local GDT Pointer
+ dw 2*8-1
+ dd gGDT-KERNEL_BASE
+
+[bits 16]
+[global APStartup]
+APStartup:
+ xchg bx, bx ; MAGIC BREAK!
+ mov ax, 0xFFFF
+ mov ds, ax
+ lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+ jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
+[bits 32]
+.ProtectedMode:
+ ; Start Paging
+ mov eax, gaInitPageDir - KERNEL_BASE
+ mov cr3, eax
+ mov eax, cr0
+ or eax, 0x80010000 ; PG and WP
+ mov cr0, eax
+ ; Jump to higher half
+ lea eax, [.higherHalf]
+ jmp eax
+.higherHalf:
+ ; Load True GDT & IDT
+ lgdt [gGDTPtr]
+ lidt [gIDTPtr]
+
+ mov eax, [gpMP_LocalAPIC]
+ mov DWORD [eax], 0
+ xor ecx, ecx
+ mov cl, BYTE [eax+0x10]
+ ; CL is now local APIC ID
+ mov cl, BYTE [gaAPIC_to_CPU+ecx]
+ ; CL is now the CPU ID
+ mov BYTE [gaCPUs+ecx*8+1], 1
+ ; Decrement the remaining CPU count
+ dec DWORD [giNumInitingCPUs]
+ ; CPU is now marked as initialised
+ sti
+.hlt:
+ hlt
+ jmp .hlt
+%endif
+
+[global GetEIP]
+GetEIP:
+ mov eax, [esp]
+ ret
+
+; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args)
+; Call a function passing the array as arguments
+[global CallWithArgArray]
+CallWithArgArray:
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+12] ; Get NArgs
+ mov edx, [ebp+16]
+
+.top:
+ mov eax, [edx+ecx*4-4]
+ push eax
+ loop .top
+
+ mov eax, [ebp+8]
+ call eax
+ lea esp, [ebp]
+ pop ebp
+ ret
+
+[section .initpd]
+[global gaInitPageDir]
+[global gaInitPageTable]
+align 0x1000
+gaInitPageDir:
+ dd gaInitPageTable-KERNEL_BASE+3 ; 0x00
+ times 1024-256-1 dd 0
+ dd gaInitPageTable-KERNEL_BASE+3 ; 0xC0
+ times 256-1 dd 0
+align 0x1000
+gaInitPageTable:
+ %assign i 0
+ %rep 1024
+ dd i*0x1000+3
+ %assign i i+1
+ %endrep
+[global Kernel_Stack_Top]
+ALIGN 0x1000
+ times 1024 dd 0
+Kernel_Stack_Top: