summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-02 01:44:40 +0200
committerMiguel <m.i@gmx.at>2018-09-02 01:44:40 +0200
commitc459fab7662eaf45df9994c828065b9fc8d4a8ac (patch)
treedf1504de1c254a18b44bad24d530531790ad8aef /kernel
parent8e3411139b27a3421e9ac75c13f14f99f6dd3137 (diff)
syscalls fine
Diffstat (limited to 'kernel')
-rw-r--r--kernel/interrupts.c12
-rw-r--r--kernel/kernel.c2
-rw-r--r--kernel/scheduler.c89
-rw-r--r--kernel/syscalls.c138
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);
}
}