From 8e3411139b27a3421e9ac75c13f14f99f6dd3137 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 2 Sep 2018 00:08:42 +0200 Subject: syscalls --- README.md | 1 + asm/GDT.asm | 81 -------------- asm/asm.h | 27 ----- asm/gdt.h | 1 + asm/gdt.s | 44 ++++++++ asm/helpers.s | 44 -------- asm/int.h | 28 ++++- asm/int.s | 135 ++++++++++++++++------- asm/int_default_handler.asm | 15 --- asm/int_irq.asm | 155 --------------------------- asm/int_kb_handler.asm | 24 ----- asm/int_mouse_handler.asm | 16 --- asm/int_syscall_handler.asm | 256 -------------------------------------------- asm/mp.asm | 1 + asm/mp.h | 1 + asm/pic.asm | 4 +- asm/pic.h | 1 + asm/pit.h | 6 +- asm/pit.s | 41 ++----- asm/read_eip.asm | 6 -- asm/start.h | 14 ++- asm/start.s | 23 ++-- asm/syscall.h | 11 -- asm/syscall.s | 17 --- asm/task.s | 9 +- asm/usermode.h | 9 +- asm/usermode.s | 4 +- driver/timer.c | 6 +- grubiso/boot/grub/grub.cfg | 8 +- kernel/gdt.c | 24 ++++- kernel/gdt.h | 45 ++++++++ kernel/interrupts.c | 170 +++++++++++++++-------------- kernel/kernel.c | 2 +- kernel/kernel.h | 10 +- kernel/scheduler.c | 196 ++++++++++++++++++--------------- kernel/scheduler.h | 1 + kernel/smashing.c | 2 - kernel/syscalls.c | 80 +++++--------- kernel/usermode.c | 36 +------ kernel/usermode.h | 45 -------- kernel/vmem.c | 3 +- newlib/syscall.h | 11 ++ newlib/syscall.s | 16 +++ userspace/foolshell.c | 3 +- userspace/init.c | 16 ++- xxx/GDT.asm | 81 ++++++++++++++ xxx/int_default_handler.asm | 15 +++ xxx/int_irq.asm | 155 +++++++++++++++++++++++++++ xxx/int_kb_handler.asm | 24 +++++ xxx/int_mouse_handler.asm | 16 +++ xxx/int_syscall_handler.asm | 256 ++++++++++++++++++++++++++++++++++++++++++++ xxx/read_eip.asm | 6 ++ 52 files changed, 1127 insertions(+), 1074 deletions(-) delete mode 100644 asm/GDT.asm delete mode 100644 asm/asm.h create mode 100644 asm/gdt.h create mode 100644 asm/gdt.s delete mode 100644 asm/helpers.s delete mode 100644 asm/int_default_handler.asm delete mode 100644 asm/int_irq.asm delete mode 100644 asm/int_kb_handler.asm delete mode 100644 asm/int_mouse_handler.asm delete mode 100644 asm/int_syscall_handler.asm create mode 100644 asm/mp.h create mode 100644 asm/pic.h delete mode 100644 asm/read_eip.asm delete mode 100644 asm/syscall.h delete mode 100644 asm/syscall.s create mode 100644 newlib/syscall.h create mode 100644 newlib/syscall.s create mode 100644 xxx/GDT.asm create mode 100644 xxx/int_default_handler.asm create mode 100644 xxx/int_irq.asm create mode 100644 xxx/int_kb_handler.asm create mode 100644 xxx/int_mouse_handler.asm create mode 100644 xxx/int_syscall_handler.asm create mode 100644 xxx/read_eip.asm diff --git a/README.md b/README.md index 2875f7e..a98d5af 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ Todos * implement posix(?) getdents instead of our own readdir. * Turning on some gcc optimizations breaks the kernel? * Writing to files (at least in ext2 ram image) +* mutex REFERENCES ========== diff --git a/asm/GDT.asm b/asm/GDT.asm deleted file mode 100644 index 444c313..0000000 --- a/asm/GDT.asm +++ /dev/null @@ -1,81 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; Global Descriptor Table -; we have the null descriptor and a code and data block for a start -; -; 0x08 code segment -; 0x10 data segment -; -; this file contains pure data -; -; -; -; - -global gdt_descriptor -global gdt_start - -gdt_start: - -gdt_null: ;null descriptor (2 x 4 bytes) - dd 0x0 - dd 0x0 - -gdt_code: - ; flags: - ; present: 1 / privilege: 00 / type: 1 - ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 - ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 - dw 0xffff ;limit - dw 0x0 ;base - db 0x0 ;base - db 10011010b ;flags - db 11001111b ;flags & seg.limit - db 0x0 ;base - -gdt_data: - ; flags: - ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 - dw 0xffff - dw 0x0 - db 0x0 - db 10010010b - db 11001111b - db 0x0 - -gdt16_code: - ; flags: - ; present: 1 / privilege: 00 / type: 1 - ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 - ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 - dw 0xffff ;limit - dw 0x0 ;base - db 0x0 ;base - db 10011010b ;flags - db 10001111b ;flags & seg.limit - db 0x0 ;base - -gdt16_data: - ; flags: - ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 - dw 0xffff - dw 0x0 - db 0x0 - db 10010010b - db 10001111b - db 0x0 - -gdt_end: - -gdt_descriptor: - dw gdt_end-gdt_start-1 - dd gdt_start - -CODE_SEG equ gdt_code - gdt_start -DATA_SEG equ gdt_data - gdt_start -CODE16_SEG equ gdt16_code - gdt_start -DATA16_SEG equ gdt16_data - gdt_start - - diff --git a/asm/asm.h b/asm/asm.h deleted file mode 100644 index 8433e4e..0000000 --- a/asm/asm.h +++ /dev/null @@ -1,27 +0,0 @@ -void pic_setup(); - -void int_kb_handler(); -void int_mouse_handler(); -void int_default_handler(); - -void int_syscall_handler(); - -void int_irq0(); -void int_irq1(); -void int_irq2(); -void int_irq3(); -void int_irq4(); -void int_irq5(); -void int_irq6(); -void int_irq7(); -void int_irq8(); -void int_irq9(); -void int_irq10(); -void int_irq11(); -void int_irq12(); -void int_irq13(); -void int_irq14(); -void int_irq15(); -void int_irq16(); -void int_irq17(); -void int_irq18(); diff --git a/asm/gdt.h b/asm/gdt.h new file mode 100644 index 0000000..f5bcbd3 --- /dev/null +++ b/asm/gdt.h @@ -0,0 +1 @@ +void asm_setup_gdt(uint32_t addr, uint32_t size) diff --git a/asm/gdt.s b/asm/gdt.s new file mode 100644 index 0000000..698dcf6 --- /dev/null +++ b/asm/gdt.s @@ -0,0 +1,44 @@ +//http://wiki.osdev.org/GDT_Tutorial +.global asm_setup_gdt +//.global tss_flush + +// call as setup_gdt(GDT,sizeof(GDT)) +asm_setup_gdt: + + // re-fill gdt_descriptor with new GDT location and size + movl 4(%esp),%eax + movl %eax, gdt_descriptor+2 + + movw 8(%esp),%ax + movw %ax, gdt_descriptor + // + + lgdt gdt_descriptor #load new descriptor table! + + // reload to take effect + reloadSegments: + + #Reload CS register containing code selector: + jmp $0x08,$reload_CS # 0x08 points at the new code selector + + reload_CS: + mov $0x10, %ax #0x10 points at the new data selector + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + + tss_flush: + + movw $0x2B,%ax # Load the index of our TSS structure - The index is + # 0x28, as it is the 5th selector and each is 8 bytes + # long, but we set the bottom two bits (making 0x2B) + # so that it has an RPL of 3, not zero. + ltr %ax # Load 0x2B into the task state register. + + ret + + + +ret diff --git a/asm/helpers.s b/asm/helpers.s deleted file mode 100644 index 135443d..0000000 --- a/asm/helpers.s +++ /dev/null @@ -1,44 +0,0 @@ -//http://wiki.osdev.org/GDT_Tutorial -.global setup_gdt -.global tss_flush - -// call as setup_gdt(GDT,sizeof(GDT)) -setup_gdt: - - // re-fill gdt_descriptor with new GDT location and size - movl 4(%esp),%eax - movl %eax, gdt_descriptor+2 - - movw 8(%esp),%ax - movw %ax, gdt_descriptor - // - - lgdt gdt_descriptor #load new descriptor table! - - // reload to take effect - reloadSegments: - - #Reload CS register containing code selector: - jmp $0x08,$reload_CS # 0x08 points at the new code selector - - reload_CS: - mov $0x10, %ax #0x10 points at the new data selector - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss - - tss_flush: - - movw $0x2B,%ax # Load the index of our TSS structure - The index is - # 0x28, as it is the 5th selector and each is 8 bytes - # long, but we set the bottom two bits (making 0x2B) - # so that it has an RPL of 3, not zero. - ltr %ax # Load 0x2B into the task state register. - - ret - - - -ret diff --git a/asm/int.h b/asm/int.h index 4af9eac..33dd16e 100644 --- a/asm/int.h +++ b/asm/int.h @@ -14,4 +14,30 @@ void int12(); void int13(); void int14(); void int15(); -void int128(); + +void int128(); // syscalls +void int129(); // scheduler +void int255(); // unhandled + +void exc0(); +void exc1(); +void exc2(); +void exc3(); +void exc4(); +void exc5(); +void exc6(); +void exc7(); +void exc8(); +void exc9(); +void exc10(); +void exc11(); +void exc12(); +void exc13(); +void exc14(); +void exc15(); +void exc16(); +void exc17(); +void exc18(); + +void asm_mouse_handler(); +void asm_kb_handler(); diff --git a/asm/int.s b/asm/int.s index f6cb9e8..156c266 100644 --- a/asm/int.s +++ b/asm/int.s @@ -17,11 +17,48 @@ .global int15 .global int128 +.global int129 +.global int255 + +.global exc0 +.global exc1 +.global exc2 +.global exc3 +.global exc4 +.global exc5 +.global exc6 +.global exc7 +.global exc8 +.global exc9 +.global exc10 +.global exc11 +.global exc12 +.global exc13 +.global exc14 +.global exc15 +.global exc16 +.global exc17 +.global exc18 //temporary .global asm_mouse_handler .global asm_kb_handler +asm_kb_handler: + push %eax + mov $0x0,%eax + in $0x60,%al + pop %eax + ret + +asm_mouse_handler: + push %eax + mov $0x0,%eax + in $0x60,%al + pop %eax + ret + +/////////////// // nothing to ack .macro ack0 @@ -44,17 +81,9 @@ pop %eax // load original .endm -// ignore return value -.macro ret0 - add $4,%esp -.endm -// put return value in %eax -.macro ret1 - pop %eax -.endm -.macro intx ack retx num func +.macro intx ack num func /* Once we arrived here the stack already contains 3x 32bit values, @@ -81,6 +110,8 @@ push $0x666 //make room for potential C functions 'return value'. //we use eax already for esp (so we can context switch) + push $0x0 //indicate if we want to return the value in ebx 0x0=NO + pusha //Push all standard registers 8 regs x 4bytes/32bit push %ds //Push data segment push %es //etc... @@ -103,42 +134,64 @@ pop %ds popa - \retx // potentially set return value to eax to return to the caller + cmp $0x0,(%esp) + je skip\num + pop %ebx + pop %ebx + jmp ret\num + skip\num: + add $8,%esp // potentially set return value to eax to return to the caller + ret\num: iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack .endm -int0: intx ack1 ret0 $0 interrupt_handler -int1: intx ack1 ret0 $1 interrupt_handler -int2: intx ack1 ret0 $2 interrupt_handler -int3: intx ack1 ret0 $3 interrupt_handler -int4: intx ack1 ret0 $4 interrupt_handler -int5: intx ack1 ret0 $5 interrupt_handler -int6: intx ack1 ret0 $6 interrupt_handler -int7: intx ack1 ret0 $7 interrupt_handler - -int8: intx ack2 ret0 $8 interrupt_handler -int9: intx ack2 ret0 $9 interrupt_handler -int10: intx ack2 ret0 $10 interrupt_handler -int11: intx ack2 ret0 $11 interrupt_handler -int12: intx ack2 ret0 $12 interrupt_handler -int13: intx ack2 ret0 $13 interrupt_handler -int14: intx ack2 ret0 $14 interrupt_handler -int15: intx ack2 ret0 $15 interrupt_handler - -int128: intx ack0 ret1 $128 interrupt_handler +.macro excx func + call \func + jmp . +.endm -asm_kb_handler: - push %eax - mov $0x0,%eax - in $0x60,%al - pop %eax - ret +int0: intx ack1 $0 interrupt_handler +int1: intx ack1 $1 interrupt_handler +int2: intx ack1 $2 interrupt_handler +int3: intx ack1 $3 interrupt_handler +int4: intx ack1 $4 interrupt_handler +int5: intx ack1 $5 interrupt_handler +int6: intx ack1 $6 interrupt_handler +int7: intx ack1 $7 interrupt_handler + +int8: intx ack2 $8 interrupt_handler +int9: intx ack2 $9 interrupt_handler +int10: intx ack2 $10 interrupt_handler +int11: intx ack2 $11 interrupt_handler +int12: intx ack2 $12 interrupt_handler +int13: intx ack2 $13 interrupt_handler +int14: intx ack2 $14 interrupt_handler +int15: intx ack2 $15 interrupt_handler + +int128: intx ack0 $128 interrupt_handler +int129: intx ack0 $129 interrupt_handler + +int255: intx ack0 $255 interrupt_handler + +exc0: excx exception_handle_0 +exc1: excx exception_handle_1 +exc2: excx exception_handle_2 +exc3: excx exception_handle_3 +exc4: excx exception_handle_4 +exc5: excx exception_handle_5 +exc6: excx exception_handle_6 +exc7: excx exception_handle_7 +exc8: excx exception_handle_8 +exc9: excx exception_handle_9 +exc10: excx exception_handle_10 +exc11: excx exception_handle_11 +exc12: excx exception_handle_12 +exc13: excx exception_handle_13 +exc14: excx exception_handle_14 +exc15: excx exception_handle_15 +exc16: excx exception_handle_16 +exc17: excx exception_handle_17 +exc18: excx exception_handle_18 -asm_mouse_handler: - push %eax - mov $0x0,%eax - in $0x60,%al - pop %eax - ret diff --git a/asm/int_default_handler.asm b/asm/int_default_handler.asm deleted file mode 100644 index 00aa1ac..0000000 --- a/asm/int_default_handler.asm +++ /dev/null @@ -1,15 +0,0 @@ -global int_default_handler -[extern int_default] - -[bits 32] -int_default_handler: - - pusha - - call int_default - - mov al, 0x20 ;Port number AND command number to Acknowledge IRQ - out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts - - popa - iret ;Interrupt-Return diff --git a/asm/int_irq.asm b/asm/int_irq.asm deleted file mode 100644 index ac8eef8..0000000 --- a/asm/int_irq.asm +++ /dev/null @@ -1,155 +0,0 @@ -global int_irq0 -global int_irq1 -global int_irq2 -global int_irq3 -global int_irq4 -global int_irq5 -global int_irq6 -global int_irq7 -global int_irq8 -global int_irq9 -global int_irq10 -global int_irq11 -global int_irq12 -global int_irq13 -global int_irq14 -global int_irq15 -global int_irq16 -global int_irq17 -global int_irq18 - -[extern exception_handle] -[extern exception_handle_0] -[extern exception_handle_1] -[extern exception_handle_2] -[extern exception_handle_3] -[extern exception_handle_4] -[extern exception_handle_5] -[extern exception_handle_6] -[extern exception_handle_7] -[extern exception_handle_8] -[extern exception_handle_9] -[extern exception_handle_10] -[extern exception_handle_11] -[extern exception_handle_12] -[extern exception_handle_13] -[extern exception_handle_14] -[extern exception_handle_15] -[extern exception_handle_16] -[extern exception_handle_17] -[extern exception_handle_18] - -[bits 32] -int_irq0: - - cli - call exception_handle_0 ;this will never return due to panic! - jmp $ - -int_irq1: - - cli - call exception_handle_1 ;this will never return due to panic! - jmp $ - -int_irq2: - - cli - call exception_handle_2 ;this will never return due to panic! - jmp $ - -int_irq3: - - cli - call exception_handle_3 ;this will never return due to panic! - jmp $ - -int_irq4: - - cli - call exception_handle_4 ;this will never return due to panic! - jmp $ - -int_irq5: - - cli - call exception_handle_5 ;this will never return due to panic! - jmp $ - -int_irq6: - - cli - call exception_handle_6 ;this will never return due to panic! - jmp $ - -int_irq7: - - cli - call exception_handle_7 ;this will never return due to panic! - jmp $ - -int_irq8: - - cli - call exception_handle_8 ;this will never return due to panic! - jmp $ - -int_irq9: - - cli - call exception_handle_9;this will never return due to panic! - jmp $ - -int_irq10: - - cli - call exception_handle_10;this will never return due to panic! - jmp $ - -int_irq11: - - cli - call exception_handle_11;this will never return due to panic! - jmp $ - -int_irq12: - - cli - call exception_handle_12 ;this will never return due to panic! - jmp $ - -int_irq13: - - cli - call exception_handle_13;this will never return due to panic! - jmp $ - -int_irq14: - - cli - call exception_handle_14 ;this will never return due to panic! - jmp $ - -int_irq15: - - cli - call exception_handle_15 ;this will never return due to panic! - jmp $ - -int_irq16: - - cli - call exception_handle_16 ;this will never return due to panic! - jmp $ - -int_irq17: - - cli - call exception_handle_17 ;this will never return due to panic! - jmp $ - -int_irq18: - - cli - call exception_handle_18;this will never return due to panic! - jmp $ diff --git a/asm/int_kb_handler.asm b/asm/int_kb_handler.asm deleted file mode 100644 index cd1b32c..0000000 --- a/asm/int_kb_handler.asm +++ /dev/null @@ -1,24 +0,0 @@ -global int_kb_handler -[extern keyboard_handle] -[extern int_default] - -[bits 32] - -int_kb_handler: - - pusha - - mov eax,0x0 - in al,0x60 - - push eax - call keyboard_handle - - pop eax - - mov al, 0x20 ;Port number AND command number to Acknowledge IRQ - out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts - - popa - -iretd ;Interrupt-Return diff --git a/asm/int_mouse_handler.asm b/asm/int_mouse_handler.asm deleted file mode 100644 index 9816950..0000000 --- a/asm/int_mouse_handler.asm +++ /dev/null @@ -1,16 +0,0 @@ -global int_mouse_handler -[extern mouse_handler] - -[bits 32] -int_mouse_handler: - pusha - - call mouse_handler - - mov al, 0x20 ; Port number AND command number to Acknowledge IRQ - out 0xa0, al ; came from slave - out 0x20, al ; Acknowledge IRQ, so we keep getting interrupts - - popa - - iret ;Interrupt-Return diff --git a/asm/int_syscall_handler.asm b/asm/int_syscall_handler.asm deleted file mode 100644 index 4031f3d..0000000 --- a/asm/int_syscall_handler.asm +++ /dev/null @@ -1,256 +0,0 @@ -global int_syscall_handler -[extern task_fork] -[extern task_exit] -[extern task_wait] - - -[extern syscall_exit] -[extern syscall_write] -[extern syscall_read] -[extern syscall_readdir] -[extern syscall_execve] -[extern syscall_open] -[extern syscall_close] -[extern syscall_isatty] -[extern syscall_lseek] -[extern syscall_sbrk] -[extern syscall_stat] -[extern syscall_fork] -[extern syscall_poll] -[extern syscall_gettimeofday] -[extern syscall_unhandled] - -[bits 32] - -pid: dd 0x0 - -int_syscall_handler: - -cmp eax, 72 -je call_fork - -cmp eax, 60 -je call_exit - -cmp eax, 77 -je call_wait - - cli - - push ebx - push ecx - push edx - - cmp eax, 61 - je call_write - - cmp eax, 62 - je call_read - - cmp eax, 63 - je call_readdir - - cmp eax, 64 - je call_execve - - cmp eax, 65 - je call_open - - cmp eax, 66 - je call_close - - cmp eax, 68 - je call_isatty - - cmp eax, 69 - je call_lseek - - cmp eax, 70 - je call_sbrk - - cmp eax, 71 - je call_timeofday - - cmp eax, 74 - je call_stat - - cmp eax, 67 - je call_stat - - cmp eax, 79 - je call_stat - - cmp eax, 80 - je call_poll - - push eax - jmp call_unhandled - - -done: - - - -done_blocking: - - pop ebx - pop ecx - pop edx - - mov ebx,eax - - sti - - iret ;Interrupt-Return - -call_wait: - - cli - - pusha ;Push all standard registers - - mov ebx, esp ;save current stack pointer in esp - mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! - - push ebx ;Push pointer to all the stuff we just pushed - - call task_wait ;Call C code - - mov esp, eax ;Replace the stack with what the C code gave us - - popa ;Put the standard registers back - - sti - - iretd ;Interrupt-Return - ;;;; - -call_exit: - - cli - - pusha ;Push all standard registers - - mov ebx, esp ;save current stack pointer in esp - mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! - - push ebx ;Push pointer to all the stuff we just pushed - - call task_exit ;Call C code - - mov esp, eax ;Replace the stack with what the C code gave us - - popa ;Put the standard registers back - - sti - - iretd ;Interrupt-Return - ;;;; - -call_fork: - - pusha ;Push all standard registers - - push ds - push es - push fs - push gs - - mov ebx, esp ; pass it in - push ebx - call task_fork ;Call C code - pop ebx - - pop ds - pop es - pop fs - pop gs - - mov [pid],eax ; save return val, so it survives popa - - popa ;Put the standard registers back - - mov ebx,[pid] - - iretd ;Interrupt-Return - -call_timeofday: - call syscall_gettimeofday - jmp done - -call_stat: - call syscall_stat - jmp done - -call_write: - call syscall_write - jmp done - -call_open: - call syscall_open - jmp done - -call_readdir: - call syscall_readdir - jmp done - -call_close: - call syscall_close - jmp done - -call_isatty: - call syscall_isatty - jmp done - -call_lseek: - call syscall_lseek - jmp done - -call_sbrk: - call syscall_sbrk - jmp done - -call_poll: - call syscall_poll - jmp done - -call_unhandled: - call syscall_unhandled - jmp done ;this should never be called, since unhandled causes kernel panic - - - ;;; THIS CALLS NEED REENABLE INTERRUPTS BEFORE calling workers - ;; TODO: redesign this shit! -call_read: - - ;//mov al, 0x20 ;Port number AND command number to Acknowledge IRQ - ;//out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts - sti - - call syscall_read - - jmp done_blocking - -call_execve: - - pusha - - mov eax,esp - mov esp,0x7000 - - push ebx - push ecx - push edx - - mov ebx,eax - call syscall_execve - - pop eax - pop eax - pop eax - - mov esp,ebx - - popa - - jmp done diff --git a/asm/mp.asm b/asm/mp.asm index 1c04f3f..e5cc26d 100644 --- a/asm/mp.asm +++ b/asm/mp.asm @@ -38,6 +38,7 @@ boot_32_pm: mov eax, 1 ; semaphore xchg eax, [LLOCK] cmp eax,1 + hlt je $ jmp $ ; loop forever here diff --git a/asm/mp.h b/asm/mp.h new file mode 100644 index 0000000..d050012 --- /dev/null +++ b/asm/mp.h @@ -0,0 +1 @@ +void smp_go(); diff --git a/asm/pic.asm b/asm/pic.asm index 28b484c..901f854 100644 --- a/asm/pic.asm +++ b/asm/pic.asm @@ -4,7 +4,7 @@ [bits 32] -global pic_setup +global asm_pic_setup %define ICW_1 0x11 ; 00010001 binary. Enables initialization mode and we are sending ICW 4 @@ -17,7 +17,7 @@ global pic_setup %define IRQ_0 0x20 ; IRQs 0-7 mapped to use interrupts 0x20-0x27 %define IRQ_8 0x28 ; IRQs 8-15 mapped to use interrupts 0x28-0x36 -pic_setup: +asm_pic_setup: ; Send ICW 1 - Begin initialization ------------------------- diff --git a/asm/pic.h b/asm/pic.h new file mode 100644 index 0000000..0daea2a --- /dev/null +++ b/asm/pic.h @@ -0,0 +1 @@ +void asm_pic_setup(); diff --git a/asm/pit.h b/asm/pit.h index 0bec3c4..d020de1 100644 --- a/asm/pit.h +++ b/asm/pit.h @@ -16,10 +16,10 @@ #include /** Init PIT - 25 times a second*/ -void pit_init(); +void asm_pit_init(); /** install this interrupt handler to your Interrupt Vector Table */ -void pit_interrupt_handler(); +void asm_pit_tick(); /** get number of ticks */ -uint32_t pit_get_ticks(); +uint32_t asm_pit_get_ticks(); diff --git a/asm/pit.s b/asm/pit.s index 34b69ec..8e16d0b 100644 --- a/asm/pit.s +++ b/asm/pit.s @@ -1,16 +1,16 @@ -.global pit_init -.global pit_interrupt_handler -.global pit_get_ticks +.global asm_pit_init +.global asm_pit_tick +.global asm_pit_get_ticks ticks: .int 0 -pit_get_ticks: +asm_pit_get_ticks: mov (ticks),%eax ret -pit_interrupt_handler: +asm_pit_tick: push %eax // persist @@ -18,38 +18,11 @@ pit_interrupt_handler: mov $ticks, %eax incl (%eax) - // ACK IRQ - //mov $0x20,%al - //out %al,$0x20 - pop %eax // load original - /////// - - /* - pusha //Push all standard registers - push %ds //Push data segment - push %es //etc... - push %fs - push %gs - - mov %esp, %eax // remember current %esp - movl $stack_top, %esp // switch to our small scheduler stack - - push %eax // set original %esp as param and... - call task_switch_next // call scheduler - mov %eax, %esp // use %esp we got from scheduler - - pop %gs - pop %fs - pop %es - pop %ds - popa - - iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack -*/ ret -pit_init: + +asm_pit_init: // configure ticking 25 times a second // 1193180 / 25 = 47727.2 diff --git a/asm/read_eip.asm b/asm/read_eip.asm deleted file mode 100644 index 3341943..0000000 --- a/asm/read_eip.asm +++ /dev/null @@ -1,6 +0,0 @@ -; http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html -[bits 32] -global read_eip -read_eip: - pop eax - jmp eax diff --git a/asm/start.h b/asm/start.h index ff30326..7b31b76 100644 --- a/asm/start.h +++ b/asm/start.h @@ -14,8 +14,20 @@ * The addresses for .smp and .multiboot are based on the assumption: * * 0x00000500 - 0x00007BFF : guaranteed free to use * * 0x00100000 - 0x00EFFFFF : free for use (if it exists) + * + * References + * ---------- + * * https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format + * * http://wiki.osdev.org/Bare_Bones */ -/** This will be called by a multiboot compilant boot-loader (i.e. grub2) */ +/** This will be called by a multiboot compilant boot-loader (i.e. grub2). + * Calls kernel_main() passing through eax and ebx: + * * eax - magic number + * * ebx - multiboot structure + * */ void _start(); +/** 16-bit entry point for application processors */ +void _start_smp(); + diff --git a/asm/start.s b/asm/start.s index bb12a7c..1d881b4 100644 --- a/asm/start.s +++ b/asm/start.s @@ -1,7 +1,9 @@ -# https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format -# http://wiki.osdev.org/Bare_Bones +.global _start +.global _start_smp +.global stack_top +.global stack_bottom -# Fill Multiboot Haeder, init stack and call kernel_main passing to params: +# Fill Multiboot Haeder, init stack and call kernel_main passing two params: # eax - magic number # ebx - multiboot structure @@ -16,7 +18,9 @@ # entry point for application processors at 0x7000 .section .smp .code16 -call smp_go # TODO: align later before going C +_start_smp: +jmp . +//call smp_go # TODO: align later before going C # Declare a header as in the Multiboot Standard. We put this into a special # section so we can force the header to be in the start of the final program. @@ -56,12 +60,8 @@ stack_top: # bootloader will jump to this position once the kernel has been loaded. It # doesn't make sense to return from this function as the bootloader is gone. .section .text -.global _start -.global stack_top -.global stack_bottom -.type _start, @function -_start: +_start: # To set up a stack, we simply set the esp register to point to the top of # our stack (as it grows downwards). @@ -73,10 +73,11 @@ _start: call kernel_main - # should never be reached - + # turn off interrupts and halt. + # this should never be reached cli hlt + .Lhang: jmp .Lhang diff --git a/asm/syscall.h b/asm/syscall.h deleted file mode 100644 index 2cadce4..0000000 --- a/asm/syscall.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Issue a System Call from Ring 3 / User Space - * - * Accepts up to 3 parameters. - * Check syscalls.h for details. - */ - -uint32_t syscall(uint32_t code, - uint32_t param_1, - uint32_t param_2, - uint32_t param_3); diff --git a/asm/syscall.s b/asm/syscall.s deleted file mode 100644 index 388b6fa..0000000 --- a/asm/syscall.s +++ /dev/null @@ -1,17 +0,0 @@ -.global syscall - -syscall: - - push %ebx // preserve (sysV abi convnetion) - - mov 0x8(%esp),%eax //syscall number - mov 0xC(%esp),%edx //p1 - mov 0x10(%esp),%ecx //p2 - mov 0x14(%esp),%ebx //p3 - - int $0x80 - mov %ebx, %eax // set as return value - - pop %ebx // preserve - ret - diff --git a/asm/task.s b/asm/task.s index 4322da5..bf80025 100644 --- a/asm/task.s +++ b/asm/task.s @@ -7,6 +7,7 @@ task_pusha: push $userfunc push $0x666 + push $0x0 pusha @@ -19,7 +20,7 @@ task_pusha: now stack looks like: - param // esp+68 + param // esp+72 returnaddy eflags @@ -44,7 +45,7 @@ task_pusha: */ - mov 68(%esp),%eax // get address of alternative stack where we want to simulate the pusha + mov 72(%esp),%eax // get address of alternative stack where we want to simulate the pusha happened mov (%esp),%ecx mov %ecx,(%eax) @@ -94,6 +95,9 @@ task_pusha: mov 60(%esp),%ecx mov %ecx,60(%eax) + mov 64(%esp),%ecx + mov %ecx,64(%eax) + pop %gs pop %fs pop %es @@ -105,5 +109,6 @@ task_pusha: pop %eax pop %eax pop %eax + pop %eax ret diff --git a/asm/usermode.h b/asm/usermode.h index 9b76db3..16597f2 100644 --- a/asm/usermode.h +++ b/asm/usermode.h @@ -1,7 +1,8 @@ -/* - * Switch to User Mode and returin to function given by pointer +/** + * @file + * Switch to User Mode and iret to function given by pointer * provide the address of a void func() that will be called without - * any params. + * any params via iret. */ -void usermode(uint32_t func); +void asm_usermode(uint32_t func); diff --git a/asm/usermode.s b/asm/usermode.s index 99cee49..71ecc1d 100644 --- a/asm/usermode.s +++ b/asm/usermode.s @@ -1,6 +1,6 @@ -.global usermode +.global asm_usermode -usermode: +asm_usermode: mov 0x4(%esp),%edx //get adress of passed : void func() //to be called in ring 3 diff --git a/driver/timer.c b/driver/timer.c index 1d04353..88c9931 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -152,16 +152,16 @@ uint64_t timer_init() { uint64_t epoch_time=get_rtc_time(); task_system_clock_start=epoch_time*25; // since pit ticks 25times a second - pit_init(); + asm_pit_init(); return epoch_time; } uint64_t timer_get_ms() { - return (pit_get_ticks()+task_system_clock_start)*40; + return (asm_pit_get_ticks()+task_system_clock_start)*40; } uint64_t timer_get_uptime_ms() { - return pit_get_ticks()*40; + return asm_pit_get_ticks()*40; } diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg index 1fd6b87..c0baeef 100644 --- a/grubiso/boot/grub/grub.cfg +++ b/grubiso/boot/grub/grub.cfg @@ -1,4 +1,10 @@ -set timeout=0 //seconds +set timeout=1 //seconds + +menuentry "FoolOS (textmode)" { + multiboot /boot/foolos.bin + set gfxpayload=text + module /boot/ext2.img +} menuentry "FoolOS (640x480x32)" { multiboot /boot/foolos.bin diff --git a/kernel/gdt.c b/kernel/gdt.c index 4df089f..562fbd5 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -1,14 +1,28 @@ -#include "kernel/kernel.h" // http://wiki.osdev.org/GDT_Tutorial +#include "kernel/kernel.h" +#include "kernel/gdt.h" #include "usermode.h" #include + #define GDT_SIZE 6 +static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE +uint64_t gdt_descriptor; -extern sys_tss; -static uint8_t gdt_struct[GDT_SIZE*8]; +//https://wiki.osdev.org/Task_State_Segment +tss_struct sys_tss; //Define the TSS as a global structure +void install_tss(uint32_t esp0){ + + // now fill each value + // set values necessary + sys_tss.ss0 = 0x10; //kernel data + sys_tss.esp0 = esp0; + + // now set the IO bitmap (not necessary, so set above limit) + // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); +} typedef struct GDT_struct { uint32_t base; @@ -130,7 +144,7 @@ void gdt_init() encodeGdtEntry(&gdt_struct[8*i],myGDT[i]); // update tss entry - install_tss(); + install_tss(0); - setup_gdt(&gdt_struct[0],8*GDT_SIZE); + asm_setup_gdt(&gdt_struct[0],8*GDT_SIZE); } diff --git a/kernel/gdt.h b/kernel/gdt.h index 4081a75..a234ea4 100644 --- a/kernel/gdt.h +++ b/kernel/gdt.h @@ -1 +1,46 @@ +// https://xarnze.com/posts/post/Tutorial:%20Entering%20User%20mode +// http://wiki.osdev.org/TSS +// http://wiki.osdev.org/Global_Descriptor_Table + +typedef volatile struct strtss{ + unsigned short link; + unsigned short link_h; + unsigned long esp0; + unsigned short ss0; + unsigned short ss0_h; + unsigned long esp1; + unsigned short ss1; + unsigned short ss1_h; + unsigned long esp2; + unsigned short ss2; + unsigned short ss2_h; + unsigned long cr3; + unsigned long eip; + unsigned long eflags; + unsigned long eax; + unsigned long ecx; + unsigned long edx; + unsigned long ebx; + unsigned long esp; + unsigned long ebp; + unsigned long esi; + unsigned long edi; + unsigned short es; + unsigned short es_h; + unsigned short cs; + unsigned short cs_h; + unsigned short ss; + unsigned short ss_h; + unsigned short ds; + unsigned short ds_h; + unsigned short fs; + unsigned short fs_h; + unsigned short gs; + unsigned short gs_h; + unsigned short ldt; + unsigned short ldt_h; + unsigned short trap; + unsigned short iomap; +}__attribute__((packed)) tss_struct; + void gdt_init(); diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 04bac9f..cf75798 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -1,14 +1,14 @@ #include "kernel/kernel.h" #include "asm/int.h" -#include "asm/asm.h" #include "asm/pit.h" #include "driver/mouse.h" #include "interrupts.h" #include "asm/x86.h" -#define INT_MAX 255 // size of our interrupts table +/** The size of our interrupts table */ +#define INT_MAX 255 -// the interrupt descriptor table +/** The interrupt descriptor table */ static struct int_desc { uint16_t addrLo; @@ -18,7 +18,7 @@ static struct int_desc uint16_t addrHi; } idt[INT_MAX]; -// interrupt descriptor table descriptor +/** The interrupt descriptor table descriptor */ static struct idt_desc { uint16_t size; @@ -26,34 +26,63 @@ static struct idt_desc uint16_t baseHi; } idtd; -uint32_t interrupt_handler(uint32_t esp, uint32_t num) +/** Sets a handler for a specific interrupt */ +static void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) { -// if(num!=0)klog("int: %d %d",num,esp); + uint64_t base=(uint32_t)&(*(uint32_t*)addr); - if(num==0) - { - pit_interrupt_handler(); - esp=task_switch_next(esp); - } + idt[irq].addrLo = base & 0xffff; + idt[irq].addrHi = (base >> 16) & 0xffff; + idt[irq].zeros=0; + idt[irq].flags=flags; + idt[irq].sel=sel; +} + +/** Installs the interrupt table */ +static void int_install() +{ + idtd.size=sizeof(struct int_desc)*INT_MAX; + uint32_t addr=(uint32_t)&idt[0]; + idtd.baseHi=addr>>16; + idtd.baseLo=0xffff&addr; + __asm__("lidt %0"::"m" (idtd)); +} - if(num==1)asm_kb_handler(); +/* + * Interrupt dispatcher + * + * Remeber that we are inside an interrupt here! + * + */ + +uint32_t interrupt_handler(uint32_t esp, uint32_t irq) +{ + if(irq==0)asm_pit_tick(); + if(irq==1)asm_kb_handler(); // TODO: put in ringbuff + if(irq==12)asm_mouse_handler();// TODO: put in ringbuff - if(num==12)asm_mouse_handler(); + // 0x80 - a syscall is coming in + if(irq==128){ - if(num==128){ uint32_t *stack=esp; uint32_t eax=stack[11]; uint32_t ebx=stack[8]; uint32_t ecx=stack[10]; uint32_t edx=stack[9]; - klog("syscall: %d (ebx=0x%08X,ecx=0x%08X,edx=0x%08X)",eax,ebx,ecx,edx); - task_wake_syscall_worker(); - esp=task_syscall(eax,ebx,ecx,edx,esp); + +// klog("syscall: %d (ebx=0x%08X,ecx=0x%08X,edx=0x%08X)",eax,ebx,ecx,edx); + + task_syscall(eax,ebx,ecx,edx); } + if(irq==0 || irq==129 || irq==128)esp=my_scheduler(esp); + + if(irq==255)kpanic("Unhandled Interrupt!"); + return esp; } +// log helpers // void errlog(uint32_t error_code) { klog("error_code: 0x%08X",error_code); @@ -66,28 +95,22 @@ void defklog(uint32_t eip, uint16_t cs, uint32_t flags) klog("eflags: 0x%08X",flags); } -void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr); - - -void exception_handle() +void show_error(uint32_t err) { - kpanic("exception interrupt"); + klog("interrupt error code: 0x%08x",err); + klog("External Event: %x",err&0b001); + klog("Location: %x",err&0b110); + klog("Selector: %x",err&0b1111111111111000); } +// + void int_default() { klog("default handler"); kpanic("unhandled interrupt (is this a panic or should just iognore?)"); } -void show_error(uint32_t err) -{ - klog("interrupt error code: 0x%08x",err); - klog("External Event: %x",err&0b001); - klog("Location: %x",err&0b110); - klog("Selector: %x",err&0b1111111111111000); -} - void exception_handle_0(){ kpanic("Divide by 0"); } void exception_handle_1(){ kpanic("Single step (debugger)"); } void exception_handle_2(){ kpanic("Non Maskable Interrupt"); } @@ -119,8 +142,7 @@ void exception_handle_14(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t u klog("error_code_RSVD: %d",error_code&8?1:0); klog("error_code_I/D: %d",error_code&16?1:0); klog("at addr: 0x%08X",x86_get_cr(2)); - - defklog(eip,cs,flags); + defklog(eip,cs,flags); kpanic("Exception: Fault: Page Fault"); } @@ -129,78 +151,60 @@ void exception_handle_16(){ kpanic("Coprocessor error"); } void exception_handle_17(){ kpanic("Alignment Check"); } void exception_handle_18(){ kpanic("Machine Check"); } -//set a handler for a specific interrupt -void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) -{ - uint64_t base=(uint32_t)&(*(uint32_t*)addr); - - idt[irq].addrLo = base & 0xffff; - idt[irq].addrHi = (base >> 16) & 0xffff; - idt[irq].zeros=0; - idt[irq].flags=flags; - idt[irq].sel=sel; -} - // set default handler for all interrupts for a start void interrupts_init(uint16_t sel) { // Setup PIC klog("setting up PIC",&idt,&idtd); - pic_setup(); + asm_pic_setup(); klog("initializing. IDT: 0x%08x, IDTD: 0x%08X",&idt,&idtd); + // Default interrupt handling for(int i=0; i 32) + // PIT interrupt handler (irq 0 => 32) int_install_ir(32, 0b10001110, 0x08,&int0); - // install keyboard interrupt handler (irq 1 => 33) + // Keyboard interrupt handler (irq 1 => 33) int_install_ir(33, 0b10001110, 0x08,&int1); - //mouse interrupt handler (irq 12 => 34) + // Mouse interrupt handler (irq 12 => 34) int_install_ir(44, 0b10001110, 0x08,&int12); - //our system calls (can be called from ring3 (0b11)) + // System Calls / they can be called from ring3 (0b11) int_install_ir(0x80, 0b11101110, 0x08,&int128); + // Wake Scheduler + int_install_ir(0x81, 0b11101110, 0x08,&int129); + // install IVT int_install(); } - -void int_install() -{ - idtd.size=sizeof(struct int_desc)*INT_MAX; - - uint32_t addr=(uint32_t)&idt[0]; - idtd.baseHi=addr>>16; - idtd.baseLo=0xffff&addr; - - __asm__("lidt %0"::"m" (idtd)); -} diff --git a/kernel/kernel.c b/kernel/kernel.c index 4406ea0..43c986c 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -59,7 +59,7 @@ void kernel_main(uint32_t eax,uint32_t ebx) // https://wiki.osdev.org/Symmetric_Multiprocessing klog("Symmetric Multi Processing (SMP) start ... "); smp_log_procdata(&procdata); - //smp_start_aps(&procdata); + smp_start_aps(&procdata); klog("Vritual Memory / Paging init ... "); pdirectory *dir=vmem_init(kernel_blocks,(uint32_t)info->framebuffer_addr); diff --git a/kernel/kernel.h b/kernel/kernel.h index 1949af5..c214c4a 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -11,7 +11,7 @@ #define FIFO_MAX_RINGBUFFERS 20 #define MAX_FIFOS 20 #define MAX_FD 20 -#define MAX_TASKS 255 +#define MAX_TASKS 10 #define MEM_PRINT_MEMORYMAP //#define LOG_SYSCALLS @@ -19,7 +19,13 @@ #define KMALLOC_MEM_SIZE 1024*1024*8 // 8MB for in kernel-memory #define NUMBER_SPINLOCKS 16 +#define S1(x) #x +#define S2(x) S1(x) + +// __FUNCTION__ ? #define kpanic(...) {log(__FILE__,0," \033[41;37m--PANIC--\033[37;40m " __VA_ARGS__ ); while(1);} -#define klog(...) log(__FILE__,10, __VA_ARGS__) +#define klog(...) log(__FILE__ ":" S2(__LINE__), 10, __VA_ARGS__) + +//#define klog(...) __asm__("nop") #endif diff --git a/kernel/scheduler.c b/kernel/scheduler.c index b367825..ee1cea2 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -1,7 +1,3 @@ -// http://hosted.cjmovie.net/TutMultitask.htm -// -// - #include "kernel.h" #include "mem.h" #include "asm/x86.h" @@ -11,53 +7,70 @@ #include "fs/fs.h" #include "fs/ext2.h" -static volatile int volatile current_task=-1; +#define NO_TASK 0xffffffff + +static volatile uint32_t current_task=NO_TASK; static volatile struct task_list_struct { - volatile int parent; - volatile bool active; - volatile uint32_t esp; // stack pointer of the task; - volatile pdirectory *vmem; // number of virtual memory table to switch to - volatile bool waiting; - volatile bool skipwait; - volatile uint32_t brk; - volatile uint32_t esp0; - - volatile bool syscall; // waiting for syscall to be processed. + volatile bool active; // is this slot used (Y/N) + volatile uint32_t pid; // process id (TODO) + + volatile uint32_t parent; // parent process id + volatile uint32_t esp; // stack pointer of the task + volatile uint32_t esp0; // tss.esp0 + volatile pdirectory *vmem; // number of virtual memory table + + volatile uint32_t brk; // memory brk pos + + volatile bool wait; // waiting for syscall to be processed. volatile uint32_t eax; volatile uint32_t ebx; volatile uint32_t ecx; volatile uint32_t edx; - }volatile task_list[MAX_TASKS]; -volatile int add_task(uint32_t esp, uint32_t vmem) +volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack) +{ + uint32_t *stk=task_list[pid].esp; + stk[14]=entry; + stk[17]=stack; +} + +volatile int add_task(uint32_t parent) { for(int i=0;i [%d] (free blocks remaining: %d )", current_task, pid,mem_get_free_blocks_count()); - return pid; + return ret; } // init task (root of all other tasks / processes) // @@ -220,27 +237,28 @@ volatile void scheduler_init(pdirectory *dir) // this is our main user task on slot 0 task_list[0].parent=0; task_list[0].active=true; - task_list[0].waiting=false; + task_list[0].wait=false; task_list[0].vmem=dir; - task_list[0].esp = kballoc(4)+4*4096; + task_list[0].esp = kballoc(4)+3*4096; task_list[0].esp0 = kballoc(4)+4*4096; - task_list[1].parent=0; - task_list[1].active=true; - task_list[1].waiting=false; - task_list[1].vmem=dir; - task_list[1].esp = kballoc(4)+4*4096; - task_list[1].esp0 = 0; // not needed by kernel space tasks +// task_list[1].parent=0; +// task_list[1].active=true; +// task_list[1].waiting=false; +// task_list[1].syscall=false; +// task_list[1].vmem=dir; +// task_list[1].esp = kballoc(4)+3*4096; +// task_list[1].esp0 = 0; // not needed by kernel space tasks task_list[2].parent=0; task_list[2].active=true; - task_list[2].waiting=false; + task_list[2].wait=false; task_list[2].vmem=dir; - task_list[2].esp = kballoc(4)+4*4096; + task_list[2].esp = kballoc(4)+3*4096; task_list[2].esp0 = 0; // not needed by kernel space tasks task_pusha(task_list[2].esp); - task_pusha(task_list[1].esp); +// task_pusha(task_list[1].esp); task_pusha(task_list[0].esp); // finally enable interrrupts so the scheduler is called (by timer) diff --git a/kernel/scheduler.h b/kernel/scheduler.h index db0e3ae..7a5bea3 100644 --- a/kernel/scheduler.h +++ b/kernel/scheduler.h @@ -1 +1,2 @@ +// http://hosted.cjmovie.net/TutMultitask.htm void scheduler_init(void *pdirectory_dir); diff --git a/kernel/smashing.c b/kernel/smashing.c index 005e784..dc092be 100644 --- a/kernel/smashing.c +++ b/kernel/smashing.c @@ -9,8 +9,6 @@ #else #define STACK_CHK_GUARD 0x595e9fbd94fda766 #endif - - uintptr_t __stack_chk_guard = STACK_CHK_GUARD; diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 56c4ae8..7a0dc50 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -22,6 +22,8 @@ static uint32_t next_fd=0; static fifo fifos[MAX_FIFOS]; static uint32_t next_fifo=0; +extern uint32_t fb_addr; + // screen / terminal term_out screen; terminal_tty tty1; @@ -54,9 +56,6 @@ int syscall_gettimeofday(struct timeval *tv, struct timezone *tz) int syscall_lseek(int file,int ptr,int dir) { - #ifdef LOG_SYSCALLS - klog("lseek (file=%d, ptr=%d, dir=%d)", file,ptr,dir); - #endif kpanic("unhandled syscall: lseek"); @@ -66,9 +65,6 @@ int syscall_lseek(int file,int ptr,int dir) // TODO: /dev/console or /dev/tty1 - /dev/ttyN int syscall_write(int file, char *buf, int len) { - #ifdef LOG_SYSCALLS - klog("[%d] write(file=%d, buf=0x%08X, len=%d)", task_get_current_pid(),file,buf,len); - #endif for(int i=0;i=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's"); @@ -258,13 +240,20 @@ int syscall_open(char *name, int flags, int mode) } else { - // FIRST TIME WE SEE THE GENIUS OF OUR ABSTRACTIONS (I HOPE...) + + // HERE WE SEE THE GENIUS OF OUR ABSTRACTIONS (I HOPE...) + + if (fb_addr<0x100000) + { screen.put_char=console_put_char; screen.update_cursor=update_cursor; - - // FIRST TIME WE SEE THE GENIUS OF OUR ABSTRACTIONS (I HOPE...) + } + else + { screen.put_char=vesa_console_put_char; screen.update_cursor=vesa_update_cursor; + } + tty1=terminal_init(&screen,NULL); @@ -284,9 +273,6 @@ int syscall_open(char *name, int flags, int mode) // int syscall_close(int file,int none1,int none2) { - #ifdef LOG_SYSCALLS - klog("close (file=%d)", file); - #endif //if(file!=0&&file!=1&&file!=2) // kpanic("unhandled syscall: close"); @@ -297,9 +283,6 @@ int syscall_close(int file,int none1,int none2) // TODO: check if file is termminal! int syscall_isatty(int file,int none1,int none2) { - #ifdef LOG_SYSCALLS - klog("isatty (file=%d)", file); - #endif return 1; } @@ -315,9 +298,6 @@ uint32_t syscall_sbrk(int incr, int none1, int none2) task_set_brk(alloc); - #ifdef LOG_SYSCALLS - klog("sbrk (incr=%d) = 0x%08X", incr,oldalloc); - #endif return oldalloc; } @@ -325,10 +305,6 @@ uint32_t syscall_sbrk(int incr, int none1, int none2) // stat, fstat, lstat int syscall_stat(const char *path, struct stat *st,int none) { - #ifdef LOG_SYSCALLS - klog("stat (path=0x%08X,stat=0x%08X)", path,st); - #endif - st->st_mode = S_IFCHR; return 0; } @@ -336,7 +312,7 @@ int syscall_stat(const char *path, struct stat *st,int none) /// there also is task_fork, task_wait, task_exit.. which is in scheduler.c //////////////////////////////////////// -uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3) +uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) { switch(nr){ @@ -345,9 +321,9 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3) case SYSCALL_CLOSE : return syscall_close(p1,p2,p3); case SYSCALL_EXECVE : - return syscall_execve(p1,p2,p3); + return syscall_execve(p1,p2,p3,pid); case SYSCALL_FORK : - return task_fork(p1,p2,p3); + return task_fork(pid); case SYSCALL_GETPID : // return syscall_getpid(p1,p2,p3); return -1; diff --git a/kernel/usermode.c b/kernel/usermode.c index 3befefd..7153e29 100644 --- a/kernel/usermode.c +++ b/kernel/usermode.c @@ -1,53 +1,26 @@ - #include "usermode.h" #include "syscalls.h" #include "kmalloc.h" -#include "asm/syscall.h" #include "asm/usermode.h" #include "kernel.h" #include -//https://wiki.osdev.org/Task_State_Segment -tss_struct sys_tss; //Define the TSS as a global structure - -static volatile uint32_t c1; -static volatile uint32_t c2; - -void install_tss(uint32_t esp0){ - - // now fill each value - // set values necessary - sys_tss.ss0 = 0x10; //kernel data - sys_tss.esp0 = esp0; - - // now set the IO bitmap (not necessary, so set above limit) - // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); -} - -void initfunc() -{ - while(1) - { - c2++; - } -} - void userfunc() { // we need enable here again (since the pushed eflags have it disabled)! x86_sti(); - // if we are pid 0, replace ourselves with /bin/init and enter via usermode + // if we are pid 0, replace ourselves with /bin/init and enter usermode if(task_get_current_pid()==0) { uint32_t alloc; uint32_t entry_global=load_elf(BIN_INIT,&alloc); task_set_brk(alloc); - usermode(entry_global); + asm_usermode(entry_global); } // kernel worker thread: SLEEPER @@ -62,10 +35,7 @@ void userfunc() // kernel worker thread: SYSCALL CHECKER if(task_get_current_pid()==2) { - while(1) - { - task_syscall_worker(); - } + task_syscall_worker(); } } diff --git a/kernel/usermode.h b/kernel/usermode.h index fafad5b..e69de29 100644 --- a/kernel/usermode.h +++ b/kernel/usermode.h @@ -1,45 +0,0 @@ -// https://xarnze.com/posts/post/Tutorial:%20Entering%20User%20mode -// http://wiki.osdev.org/TSS -// http://wiki.osdev.org/Global_Descriptor_Table - -typedef volatile struct strtss{ - unsigned short link; - unsigned short link_h; - unsigned long esp0; - unsigned short ss0; - unsigned short ss0_h; - unsigned long esp1; - unsigned short ss1; - unsigned short ss1_h; - unsigned long esp2; - unsigned short ss2; - unsigned short ss2_h; - unsigned long cr3; - unsigned long eip; - unsigned long eflags; - unsigned long eax; - unsigned long ecx; - unsigned long edx; - unsigned long ebx; - unsigned long esp; - unsigned long ebp; - unsigned long esi; - unsigned long edi; - unsigned short es; - unsigned short es_h; - unsigned short cs; - unsigned short cs_h; - unsigned short ss; - unsigned short ss_h; - unsigned short ds; - unsigned short ds_h; - unsigned short fs; - unsigned short fs_h; - unsigned short gs; - unsigned short gs_h; - unsigned short ldt; - unsigned short ldt_h; - unsigned short trap; - unsigned short iomap; -}__attribute__((packed)) tss_struct; - diff --git a/kernel/vmem.c b/kernel/vmem.c index 5bf530f..d026e9e 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -8,7 +8,7 @@ #include "vmem.h" static uint32_t kernel_pages; -static uint32_t fb_addr; +uint32_t fb_addr; // TODO : why is the frame not 0xfffff?? enum PAGE_PTE_FLAGS @@ -299,6 +299,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) phys_addr=fb_addr; virt_addr=fb_addr; + if(fb_addr>0x100000) for(int j=0;j<4;j++) { diff --git a/newlib/syscall.h b/newlib/syscall.h new file mode 100644 index 0000000..2cadce4 --- /dev/null +++ b/newlib/syscall.h @@ -0,0 +1,11 @@ +/* + * Issue a System Call from Ring 3 / User Space + * + * Accepts up to 3 parameters. + * Check syscalls.h for details. + */ + +uint32_t syscall(uint32_t code, + uint32_t param_1, + uint32_t param_2, + uint32_t param_3); diff --git a/newlib/syscall.s b/newlib/syscall.s new file mode 100644 index 0000000..abce63a --- /dev/null +++ b/newlib/syscall.s @@ -0,0 +1,16 @@ +.global syscall + +syscall: + + push %ebx // preserve (sysV abi convnetion) + + mov 0x8(%esp),%eax //syscall number + mov 0xC(%esp),%edx //p1 + mov 0x10(%esp),%ecx //p2 + mov 0x14(%esp),%ebx //p3 + + int $0x80 + mov %ebx, %eax // set as return value + + pop %ebx // preserve + ret diff --git a/userspace/foolshell.c b/userspace/foolshell.c index c5c3b42..38a6e55 100644 --- a/userspace/foolshell.c +++ b/userspace/foolshell.c @@ -69,7 +69,8 @@ int main(int argc, char **argv) //char *buf=malloc(256); char *buf=calloc(sizeof(char),256); - printf("setvbuf returned %i\n",setvbuf(stdin,NULL,_IONBF,0)); +// printf("setvbuf returned %i\n", + setvbuf(stdin,NULL,_IONBF,0); while(1) { diff --git a/userspace/init.c b/userspace/init.c index 7474b11..6484b78 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -1,7 +1,16 @@ #include +#include + int main(int argc, char **argv) { + char *argv1[]={"/bin/foolshell",0}; + char *env1[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; + + time_t ltime; + time(<ime); + printf("Current time: %s", ctime(<ime)); + printf("fool-init: spawning a Fool's Shell\n"); //while(1)printf("x"); @@ -11,13 +20,12 @@ int main(int argc, char **argv) { int pid=_fork(); + printf("fool-init: pid: %i\n",pid); int status; if(pid==0) { - char *argv[]={"/bin/foolshell",0}; - char *env[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; - _execve("/bin/foolshell",argv,env); // replace process with our foolshell :) + _execve("/bin/foolshell",argv1,env1); // replace process with our foolshell :) //execve("/bin/clear",argv,env); // replace process with our foolshell :) puts("FATAL ERROR: Something terrible happened. Unable to Execute SHELL!"); while(1);// hang @@ -25,7 +33,9 @@ int main(int argc, char **argv) // wait until our child process state changes (exits) // and respawn SHELL + while(1); _wait(&status); + printf("fool-init: catched exit of process %d.\n",pid); printf("fool-init: respawning a Fools Shell\n"); diff --git a/xxx/GDT.asm b/xxx/GDT.asm new file mode 100644 index 0000000..53458ba --- /dev/null +++ b/xxx/GDT.asm @@ -0,0 +1,81 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Global Descriptor Table +; we have the null descriptor and a code and data block for a start +; +; 0x08 code segment +; 0x10 data segment +; +; this file contains pure data +; +; +; +; + +;global gdt_descriptor +;global gdt_start + +gdt_start: + +gdt_null: ;null descriptor (2 x 4 bytes) + dd 0x0 + dd 0x0 + +gdt_code: + ; flags: + ; present: 1 / privilege: 00 / type: 1 + ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 + ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 + dw 0xffff ;limit + dw 0x0 ;base + db 0x0 ;base + db 10011010b ;flags + db 11001111b ;flags & seg.limit + db 0x0 ;base + +gdt_data: + ; flags: + ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 11001111b + db 0x0 + +gdt16_code: + ; flags: + ; present: 1 / privilege: 00 / type: 1 + ; code: 1 / conforming: 0 / readable: 1 / accessed: 0 + ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0 + dw 0xffff ;limit + dw 0x0 ;base + db 0x0 ;base + db 10011010b ;flags + db 10001111b ;flags & seg.limit + db 0x0 ;base + +gdt16_data: + ; flags: + ; code: 0 / expand down: 0 / writable: 1 / accessed: 0 + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 10001111b + db 0x0 + +gdt_end: + +gdt_descriptor: + dw gdt_end-gdt_start-1 + dd gdt_start + +CODE_SEG equ gdt_code - gdt_start +DATA_SEG equ gdt_data - gdt_start +CODE16_SEG equ gdt16_code - gdt_start +DATA16_SEG equ gdt16_data - gdt_start + + diff --git a/xxx/int_default_handler.asm b/xxx/int_default_handler.asm new file mode 100644 index 0000000..00aa1ac --- /dev/null +++ b/xxx/int_default_handler.asm @@ -0,0 +1,15 @@ +global int_default_handler +[extern int_default] + +[bits 32] +int_default_handler: + + pusha + + call int_default + + mov al, 0x20 ;Port number AND command number to Acknowledge IRQ + out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts + + popa + iret ;Interrupt-Return diff --git a/xxx/int_irq.asm b/xxx/int_irq.asm new file mode 100644 index 0000000..ac8eef8 --- /dev/null +++ b/xxx/int_irq.asm @@ -0,0 +1,155 @@ +global int_irq0 +global int_irq1 +global int_irq2 +global int_irq3 +global int_irq4 +global int_irq5 +global int_irq6 +global int_irq7 +global int_irq8 +global int_irq9 +global int_irq10 +global int_irq11 +global int_irq12 +global int_irq13 +global int_irq14 +global int_irq15 +global int_irq16 +global int_irq17 +global int_irq18 + +[extern exception_handle] +[extern exception_handle_0] +[extern exception_handle_1] +[extern exception_handle_2] +[extern exception_handle_3] +[extern exception_handle_4] +[extern exception_handle_5] +[extern exception_handle_6] +[extern exception_handle_7] +[extern exception_handle_8] +[extern exception_handle_9] +[extern exception_handle_10] +[extern exception_handle_11] +[extern exception_handle_12] +[extern exception_handle_13] +[extern exception_handle_14] +[extern exception_handle_15] +[extern exception_handle_16] +[extern exception_handle_17] +[extern exception_handle_18] + +[bits 32] +int_irq0: + + cli + call exception_handle_0 ;this will never return due to panic! + jmp $ + +int_irq1: + + cli + call exception_handle_1 ;this will never return due to panic! + jmp $ + +int_irq2: + + cli + call exception_handle_2 ;this will never return due to panic! + jmp $ + +int_irq3: + + cli + call exception_handle_3 ;this will never return due to panic! + jmp $ + +int_irq4: + + cli + call exception_handle_4 ;this will never return due to panic! + jmp $ + +int_irq5: + + cli + call exception_handle_5 ;this will never return due to panic! + jmp $ + +int_irq6: + + cli + call exception_handle_6 ;this will never return due to panic! + jmp $ + +int_irq7: + + cli + call exception_handle_7 ;this will never return due to panic! + jmp $ + +int_irq8: + + cli + call exception_handle_8 ;this will never return due to panic! + jmp $ + +int_irq9: + + cli + call exception_handle_9;this will never return due to panic! + jmp $ + +int_irq10: + + cli + call exception_handle_10;this will never return due to panic! + jmp $ + +int_irq11: + + cli + call exception_handle_11;this will never return due to panic! + jmp $ + +int_irq12: + + cli + call exception_handle_12 ;this will never return due to panic! + jmp $ + +int_irq13: + + cli + call exception_handle_13;this will never return due to panic! + jmp $ + +int_irq14: + + cli + call exception_handle_14 ;this will never return due to panic! + jmp $ + +int_irq15: + + cli + call exception_handle_15 ;this will never return due to panic! + jmp $ + +int_irq16: + + cli + call exception_handle_16 ;this will never return due to panic! + jmp $ + +int_irq17: + + cli + call exception_handle_17 ;this will never return due to panic! + jmp $ + +int_irq18: + + cli + call exception_handle_18;this will never return due to panic! + jmp $ diff --git a/xxx/int_kb_handler.asm b/xxx/int_kb_handler.asm new file mode 100644 index 0000000..cd1b32c --- /dev/null +++ b/xxx/int_kb_handler.asm @@ -0,0 +1,24 @@ +global int_kb_handler +[extern keyboard_handle] +[extern int_default] + +[bits 32] + +int_kb_handler: + + pusha + + mov eax,0x0 + in al,0x60 + + push eax + call keyboard_handle + + pop eax + + mov al, 0x20 ;Port number AND command number to Acknowledge IRQ + out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts + + popa + +iretd ;Interrupt-Return diff --git a/xxx/int_mouse_handler.asm b/xxx/int_mouse_handler.asm new file mode 100644 index 0000000..9816950 --- /dev/null +++ b/xxx/int_mouse_handler.asm @@ -0,0 +1,16 @@ +global int_mouse_handler +[extern mouse_handler] + +[bits 32] +int_mouse_handler: + pusha + + call mouse_handler + + mov al, 0x20 ; Port number AND command number to Acknowledge IRQ + out 0xa0, al ; came from slave + out 0x20, al ; Acknowledge IRQ, so we keep getting interrupts + + popa + + iret ;Interrupt-Return diff --git a/xxx/int_syscall_handler.asm b/xxx/int_syscall_handler.asm new file mode 100644 index 0000000..4031f3d --- /dev/null +++ b/xxx/int_syscall_handler.asm @@ -0,0 +1,256 @@ +global int_syscall_handler +[extern task_fork] +[extern task_exit] +[extern task_wait] + + +[extern syscall_exit] +[extern syscall_write] +[extern syscall_read] +[extern syscall_readdir] +[extern syscall_execve] +[extern syscall_open] +[extern syscall_close] +[extern syscall_isatty] +[extern syscall_lseek] +[extern syscall_sbrk] +[extern syscall_stat] +[extern syscall_fork] +[extern syscall_poll] +[extern syscall_gettimeofday] +[extern syscall_unhandled] + +[bits 32] + +pid: dd 0x0 + +int_syscall_handler: + +cmp eax, 72 +je call_fork + +cmp eax, 60 +je call_exit + +cmp eax, 77 +je call_wait + + cli + + push ebx + push ecx + push edx + + cmp eax, 61 + je call_write + + cmp eax, 62 + je call_read + + cmp eax, 63 + je call_readdir + + cmp eax, 64 + je call_execve + + cmp eax, 65 + je call_open + + cmp eax, 66 + je call_close + + cmp eax, 68 + je call_isatty + + cmp eax, 69 + je call_lseek + + cmp eax, 70 + je call_sbrk + + cmp eax, 71 + je call_timeofday + + cmp eax, 74 + je call_stat + + cmp eax, 67 + je call_stat + + cmp eax, 79 + je call_stat + + cmp eax, 80 + je call_poll + + push eax + jmp call_unhandled + + +done: + + + +done_blocking: + + pop ebx + pop ecx + pop edx + + mov ebx,eax + + sti + + iret ;Interrupt-Return + +call_wait: + + cli + + pusha ;Push all standard registers + + mov ebx, esp ;save current stack pointer in esp + mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! + + push ebx ;Push pointer to all the stuff we just pushed + + call task_wait ;Call C code + + mov esp, eax ;Replace the stack with what the C code gave us + + popa ;Put the standard registers back + + sti + + iretd ;Interrupt-Return + ;;;; + +call_exit: + + cli + + pusha ;Push all standard registers + + mov ebx, esp ;save current stack pointer in esp + mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! + + push ebx ;Push pointer to all the stuff we just pushed + + call task_exit ;Call C code + + mov esp, eax ;Replace the stack with what the C code gave us + + popa ;Put the standard registers back + + sti + + iretd ;Interrupt-Return + ;;;; + +call_fork: + + pusha ;Push all standard registers + + push ds + push es + push fs + push gs + + mov ebx, esp ; pass it in + push ebx + call task_fork ;Call C code + pop ebx + + pop ds + pop es + pop fs + pop gs + + mov [pid],eax ; save return val, so it survives popa + + popa ;Put the standard registers back + + mov ebx,[pid] + + iretd ;Interrupt-Return + +call_timeofday: + call syscall_gettimeofday + jmp done + +call_stat: + call syscall_stat + jmp done + +call_write: + call syscall_write + jmp done + +call_open: + call syscall_open + jmp done + +call_readdir: + call syscall_readdir + jmp done + +call_close: + call syscall_close + jmp done + +call_isatty: + call syscall_isatty + jmp done + +call_lseek: + call syscall_lseek + jmp done + +call_sbrk: + call syscall_sbrk + jmp done + +call_poll: + call syscall_poll + jmp done + +call_unhandled: + call syscall_unhandled + jmp done ;this should never be called, since unhandled causes kernel panic + + + ;;; THIS CALLS NEED REENABLE INTERRUPTS BEFORE calling workers + ;; TODO: redesign this shit! +call_read: + + ;//mov al, 0x20 ;Port number AND command number to Acknowledge IRQ + ;//out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts + sti + + call syscall_read + + jmp done_blocking + +call_execve: + + pusha + + mov eax,esp + mov esp,0x7000 + + push ebx + push ecx + push edx + + mov ebx,eax + call syscall_execve + + pop eax + pop eax + pop eax + + mov esp,ebx + + popa + + jmp done diff --git a/xxx/read_eip.asm b/xxx/read_eip.asm new file mode 100644 index 0000000..3341943 --- /dev/null +++ b/xxx/read_eip.asm @@ -0,0 +1,6 @@ +; http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html +[bits 32] +global read_eip +read_eip: + pop eax + jmp eax -- cgit v1.2.3