From 8e3411139b27a3421e9ac75c13f14f99f6dd3137 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 2 Sep 2018 00:08:42 +0200 Subject: syscalls --- 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 +- 12 files changed, 301 insertions(+), 313 deletions(-) (limited to 'kernel') 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++) { -- cgit v1.2.3