From b7d27cb988daadd457370e7e1a19aaec342e8415 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 13 Jul 2010 20:29:34 +0800 Subject: [PATCH] Increased user stack size, fiddling with error recovery - Also, next time use 0x1000, not 4069 (as opposed to 4096) --- Kernel/arch/x86/include/mm_virt.h | 2 +- Kernel/arch/x86/mm_virt.c | 7 + Kernel/arch/x86/proc.asm | 52 ++++- Kernel/arch/x86/proc.c | 2 +- Kernel/arch/x86/start.asm | 377 +++++++++++++++--------------- Kernel/debug.c | 8 +- 6 files changed, 249 insertions(+), 199 deletions(-) diff --git a/Kernel/arch/x86/include/mm_virt.h b/Kernel/arch/x86/include/mm_virt.h index 2664a104..5e4712f6 100644 --- a/Kernel/arch/x86/include/mm_virt.h +++ b/Kernel/arch/x86/include/mm_virt.h @@ -8,7 +8,7 @@ // - Memory Layout #define MM_USER_MIN 0x00200000 -#define USER_STACK_SZ 0x00010000 +#define USER_STACK_SZ 0x00020000 // 128 KiB #define USER_STACK_TOP 0x00800000 #define USER_LIB_MAX 0xBC000000 #define MM_USER_MAX 0xBC000000 // Top load address for user libraries diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index 7cdf5cd8..fc689f78 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -247,6 +247,13 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) //MM_DumpTables(0, -1); + // Register Dump + Log("EAX %08x ECX %08x EDX %08x EBX %08x", Regs->eax, Regs->ecx, Regs->edx, Regs->ebx); + Log("ESP %08x EBP %08x ESI %08x EDI %08x", Regs->esp, Regs->ebp, Regs->esi, Regs->edi); + //Log("SS:ESP %04x:%08x", Regs->ss, Regs->esp); + Log("CS:EIP %04x:%08x", Regs->cs, Regs->eip); + Log("DS %04x ES %04x FS %04x GS %04x", Regs->ds, Regs->es, Regs->fs, Regs->gs); + Panic("Page Fault at 0x%x (Accessed 0x%x)", Regs->eip, Addr); } diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm index 1cf1f962..ebc1664e 100644 --- a/Kernel/arch/x86/proc.asm +++ b/Kernel/arch/x86/proc.asm @@ -84,7 +84,7 @@ Proc_ReturnToUser: ; 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 @@ -92,12 +92,43 @@ Proc_ReturnToUser: ; 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 @@ -113,6 +144,14 @@ Proc_ReturnToUser: 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: @@ -122,6 +161,7 @@ GetCPUNum: shr ax, 3 ; ax /= 8 ret +; Usermode code exported by the kernel [section .usertext] User_Syscall_RetAndExit: push eax diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 2f59472a..5406d2e4 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -583,7 +583,7 @@ Uint Proc_MakeUserStack(void) if(i != -1) return 0; // Allocate Stack - Allocate incrementally to clean up MM_Dump output - for( i = 0; i < USER_STACK_SZ/4069; i++ ) + for( i = 0; i < USER_STACK_SZ/0x1000; i++ ) MM_Allocate( base + (i<<12) ); return base + USER_STACK_SZ; diff --git a/Kernel/arch/x86/start.asm b/Kernel/arch/x86/start.asm index 8b3e18c5..6b6a6116 100644 --- a/Kernel/arch/x86/start.asm +++ b/Kernel/arch/x86/start.asm @@ -1,191 +1,192 @@ -; 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 +; 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 - 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: + ; 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: diff --git a/Kernel/debug.c b/Kernel/debug.c index e4f92a7a..ac5c0597 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -1,6 +1,8 @@ /* * AcessOS Microkernel Version * debug.c + * + * TODO: Move the Debug_putchar methods out to the arch/ tree */ #include #include @@ -38,9 +40,9 @@ int putDebugChar(char ch) if(!gbGDB_SerialSetup) { outb(GDB_SERIAL_PORT + 1, 0x00); // Disable all interrupts outb(GDB_SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - outb(GDB_SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - outb(GDB_SERIAL_PORT + 1, 0x00); // (hi byte) - outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(GDB_SERIAL_PORT + 0, 0x0C); // Set divisor to 12 (lo byte) 9600 baud + outb(GDB_SERIAL_PORT + 1, 0x00); // (base is (hi byte) + outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit (8N1) outb(GDB_SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it outb(GDB_SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set gbDebug_SerialSetup = 1; -- 2.20.1