diff options
| author | Miguel <m.i@gmx.at> | 2018-09-02 01:44:40 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-02 01:44:40 +0200 |
| commit | c459fab7662eaf45df9994c828065b9fc8d4a8ac (patch) | |
| tree | df1504de1c254a18b44bad24d530531790ad8aef /kernel | |
| parent | 8e3411139b27a3421e9ac75c13f14f99f6dd3137 (diff) | |
syscalls fine
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/interrupts.c | 12 | ||||
| -rw-r--r-- | kernel/kernel.c | 2 | ||||
| -rw-r--r-- | kernel/scheduler.c | 89 | ||||
| -rw-r--r-- | kernel/syscalls.c | 138 |
4 files changed, 126 insertions, 115 deletions
diff --git a/kernel/interrupts.c b/kernel/interrupts.c index cf75798..3ce33c4 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -58,8 +58,13 @@ static void int_install() 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 + + // mouse and kb + if(irq==1 || irq==12 ){ + uint32_t in=x86_inb(0x60); + if(irq=1)keyboard_handle(in); // do this in separate thread! +// klog("0x60 in %d",in); + } // 0x80 - a syscall is coming in if(irq==128){ @@ -73,9 +78,10 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // klog("syscall: %d (ebx=0x%08X,ecx=0x%08X,edx=0x%08X)",eax,ebx,ecx,edx); task_syscall(eax,ebx,ecx,edx); + esp=my_scheduler(esp,2); // force scheduling of pid=2 (kernel worker) } - if(irq==0 || irq==129 || irq==128)esp=my_scheduler(esp); + if(irq==0 || irq==129)esp=my_scheduler(esp,-1); // autoschedule if(irq==255)kpanic("Unhandled Interrupt!"); diff --git a/kernel/kernel.c b/kernel/kernel.c index 43c986c..4406ea0 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/scheduler.c b/kernel/scheduler.c index ee1cea2..a16dd02 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -92,6 +92,7 @@ void task_syscall_worker() { //klog("checking if any pending syscalls."); + bool nowork=true; for(int i=0;i<MAX_TASKS;i++) { if(task_list[i].wait) @@ -99,6 +100,24 @@ void task_syscall_worker() // klog("task %d waiting on syscall %d. processing...",i,task_list[i].eax); task_list[2].vmem=task_list[i].vmem; // switch syscall worker to pagedir of calling userprog x86_set_page_directory(task_list[2].vmem); + + if(task_list[i].eax==SYSCALL_WAIT) + { + continue; + } + + if(task_list[i].eax==SYSCALL_READ) + { + uint32_t ok= chk_syscall_read( + task_list[i].edx, + task_list[i].ecx, + task_list[i].ebx + ); + if(!ok)continue; + } + + nowork=false; + uint32_t ret= syscall_generic(task_list[i].eax, task_list[i].edx, task_list[i].ecx, @@ -113,8 +132,9 @@ void task_syscall_worker() } } - task_list[2].wait=true; - __asm__("int $0x81"); // wake scheduler! + //task_list[2].wait=true; + if (nowork)__asm__("hlt"); + else __asm__("int $0x81"); // wake scheduler! } } @@ -128,7 +148,7 @@ void task_syscall_worker() // // we need to return a NEW stack pointer where popa will get the registers the new task requires // -volatile uint32_t my_scheduler(uint32_t oldesp) +volatile uint32_t my_scheduler(uint32_t oldesp,uint32_t force_pid) { // static bool first=true; @@ -136,6 +156,15 @@ volatile uint32_t my_scheduler(uint32_t oldesp) if(!first) task_list[current_task].esp=oldesp; first=false; // + if(force_pid>-1) + { + int pid=force_pid; + current_task=pid; + install_tss(task_list[pid].esp0); + + x86_set_page_directory(task_list[pid].vmem); + return task_list[pid].esp; + } for(int i=0;i<MAX_TASKS;i++) { @@ -170,51 +199,21 @@ volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t //TODO: free vmem too! //TODO: notify waiting parent when child finished; -volatile uint32_t task_exit(uint32_t oldesp) +volatile uint32_t task_exit(uint32_t pid) { - /* - - task_list[current_task].active=false; - int parent_pid=task_list[current_task].parent; - - klog("[%d] exit ", current_task); - - if(task_list[parent_pid].active) - { - if(task_list[parent_pid].waiting) - { - - klog("[%d] wake up", parent_pid); - task_list[parent_pid].waiting=false; - } - else - { -// klog("[%d] skipwait", parent_pid); -// task_list[parent_pid].skipwait=true; - } - - } - - vmem_free_dir(task_list[current_task].vmem); - - return my_scheduler(oldesp); - */ - + task_list[pid].active=false; + int parent_pid=task_list[pid].parent; + if(task_list[parent_pid].wait&&task_list[parent_pid].eax==SYSCALL_WAIT) + task_list[parent_pid].wait=false; + klog("[%d] exit", pid); + vmem_free_dir(task_list[pid].vmem); } -volatile uint32_t task_wait(uint32_t oldesp) -{ /* - klog("[%d] wait", current_task); - if(task_list[current_task].skipwait) - { - task_list[current_task].skipwait=false; - } - else - { - task_list[current_task].waiting=true; - } - return my_scheduler(oldesp); - */ +volatile uint32_t task_wait(uint32_t pid) +{ + klog("[%d] wait", pid); + task_list[pid].wait=true; + task_list[pid].eax=SYSCALL_WAIT; } volatile uint32_t task_fork(uint32_t pid) diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 7a0dc50..2a31a81 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -20,6 +20,7 @@ static fd fds[MAX_FD]; static uint32_t next_fd=0; static fifo fifos[MAX_FIFOS]; +static uint32_t fifo_data_len[MAX_FIFOS]; static uint32_t next_fifo=0; extern uint32_t fb_addr; @@ -69,30 +70,32 @@ int syscall_write(int file, char *buf, int len) for(int i=0;i<len;i++) { fd_write(&fds[file],buf[i]); + fifo_data_len[file]++; } return len; } +int chk_syscall_read(int file, char *buf, int len) +{ + if(len> fifo_data_len[file])return 0; + return 1; +} + int syscall_read(int file, char *buf, int len) { //file 0 = stdin , file 1 = stdout , file 2 = stderr - char c; int l=0; - while(1) - { - while(!fd_has(&fds[file])); c=fd_read(&fds[file]); - + fifo_data_len[file]--; *buf=c; buf++; l++; if(l==len)return l; if(c=='\n')return l; - } } //TODO: replace with dirent! @@ -192,11 +195,14 @@ int syscall_execve(char *name, char **argv, char **env,int pid) if(!entry_global) { - kpanic("error loading %s",name); return -1; // errror loading } - task_reset(pid,entry_global,0x08fff000); + uint32_t *stack=0x08fff000; + *++stack=argv1; + *++stack=arg_count; + *++stack=env1; + task_reset(pid,entry_global,stack); return 0; /* try to move this to asm */ @@ -230,9 +236,9 @@ int get_max_fd() // TODO: allow opening existing files/named pipes int syscall_open(char *name, int flags, int mode) { - if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's"); + if(0!=strcmp(name,"term")) { fifos[next_fifo]=fifo_create_buffered(1); @@ -243,18 +249,17 @@ int syscall_open(char *name, int flags, int mode) // HERE WE SEE THE GENIUS OF OUR ABSTRACTIONS (I HOPE...) - if (fb_addr<0x100000) + if (fb_addr<0x100000) // text-mode { - screen.put_char=console_put_char; - screen.update_cursor=update_cursor; + screen.put_char=console_put_char; + screen.update_cursor=update_cursor; } - else + else // framebuffer mode { - screen.put_char=vesa_console_put_char; - screen.update_cursor=vesa_update_cursor; + screen.put_char=vesa_console_put_char; + screen.update_cursor=vesa_update_cursor; } - tty1=terminal_init(&screen,NULL); fifos[next_fifo].data=&tty1; @@ -263,6 +268,8 @@ int syscall_open(char *name, int flags, int mode) fds[next_fd]=fd_from_fifo(&fifos[next_fifo]); } + fifo_data_len[next_fifo]=0; + next_fifo++; next_fd++; @@ -314,56 +321,55 @@ int syscall_stat(const char *path, struct stat *st,int none) uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) { - switch(nr){ - case SYSCALL_EXIT : - return task_exit(p1,p2,p3); - case SYSCALL_CLOSE : - return syscall_close(p1,p2,p3); - case SYSCALL_EXECVE : - return syscall_execve(p1,p2,p3,pid); - case SYSCALL_FORK : - return task_fork(pid); - case SYSCALL_GETPID : -// return syscall_getpid(p1,p2,p3); - return -1; - case SYSCALL_ISATTY : - return syscall_isatty(p1,p2,p3); - case SYSCALL_LINK : -// return syscall_link(p1,p2,p3); - return -1; - case SYSCALL_LSEEK : - return syscall_lseek(p1,p2,p3); - case SYSCALL_OPEN : - return syscall_open(p1,p2,p3); - case SYSCALL_READ : - return syscall_read(p1,p2,p3); - case SYSCALL_SBRK : - return syscall_sbrk(p1,p2,p3); - case SYSCALL_STAT : - return syscall_stat(p1,p2,p3); - case SYSCALL_FSTAT : - return syscall_stat(p1,p2,p3); - case SYSCALL_LSTAT : - return syscall_stat(p1,p2,p3); - case SYSCALL_TIMES : -// return syscall_times(p1,p2,p3); - return -1; - case SYSCALL_UNLINK : -// return syscall_unlink(p1,p2,p3); - return -1; - case SYSCALL_WAIT : - return task_wait(p1,p2,p3); - case SYSCALL_WRITE : - return syscall_write(p1,p2,p3); - case SYSCALL_GETTIMEOFDAY: - return syscall_gettimeofday(p1,p2); - case SYSCALL_READDIR : - return syscall_readdir(p1,p2,p3); - case SYSCALL_KILL : -// return task_kill(p1,p2,p3); - return -1; - case SYSCALL_POLL : - return syscall_poll(p1); + case SYSCALL_EXIT : + return task_exit(pid); + case SYSCALL_CLOSE : + return syscall_close(p1,p2,p3); + case SYSCALL_EXECVE : + return syscall_execve(p1,p2,p3,pid); + case SYSCALL_FORK : + return task_fork(pid); + case SYSCALL_GETPID : + // return syscall_getpid(p1,p2,p3); + return -1; + case SYSCALL_ISATTY : + return syscall_isatty(p1,p2,p3); + case SYSCALL_LINK : + // return syscall_link(p1,p2,p3); + return -1; + case SYSCALL_LSEEK : + return syscall_lseek(p1,p2,p3); + case SYSCALL_OPEN : + return syscall_open(p1,p2,p3); + case SYSCALL_READ : + return syscall_read(p1,p2,p3); + case SYSCALL_SBRK : + return syscall_sbrk(p1,p2,p3); + case SYSCALL_STAT : + return syscall_stat(p1,p2,p3); + case SYSCALL_FSTAT : + return syscall_stat(p1,p2,p3); + case SYSCALL_LSTAT : + return syscall_stat(p1,p2,p3); + case SYSCALL_TIMES : + // return syscall_times(p1,p2,p3); + return -1; + case SYSCALL_UNLINK : + // return syscall_unlink(p1,p2,p3); + return -1; + case SYSCALL_WAIT : + return task_wait(pid); + case SYSCALL_WRITE : + return syscall_write(p1,p2,p3); + case SYSCALL_GETTIMEOFDAY: + return syscall_gettimeofday(p1,p2); + case SYSCALL_READDIR : + return syscall_readdir(p1,p2,p3); + case SYSCALL_KILL : + // return task_kill(p1,p2,p3); + return -1; + case SYSCALL_POLL : + return syscall_poll(p1); } } |
