summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-01 12:10:13 +0200
committerMiguel <m.i@gmx.at>2018-09-01 12:10:13 +0200
commit51ab94a29f64de42e3dec3a3ef0ec6a94cda28a6 (patch)
treec2cf5f0b31c2f80ac815dc366ece52a42983219f /kernel
parentd52c3d119dbbbf2a9573e7698a878cf74afdd08c (diff)
working on new syscalls
Diffstat (limited to 'kernel')
-rw-r--r--kernel/interrupts.c24
-rw-r--r--kernel/kernel.c7
-rw-r--r--kernel/mem.c22
-rw-r--r--kernel/scheduler.c69
-rw-r--r--kernel/syscalls.c63
-rw-r--r--kernel/usermode.c15
-rw-r--r--kernel/vmem.c7
-rw-r--r--kernel/vmem.h4
8 files changed, 174 insertions, 37 deletions
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index 6e7e2ff..0343ad3 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -27,9 +27,31 @@ static struct idt_desc
uint16_t baseHi;
} idtd;
-uint32_t interrupt_handler(uint32_t num, uint32_t esp)
+uint32_t interrupt_handler(uint32_t esp, uint32_t num)
{
if(num!=0)klog("int: %d %d",num,esp);
+
+ if(num==0)
+ {
+ pit_interrupt_handler();
+ esp=task_switch_next(esp);
+ }
+
+ if(num==1)asm_kb_handler();
+
+ if(num==12)asm_mouse_handler();
+
+ 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);
+ }
+
return esp;
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 1969102..4406ea0 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -51,7 +51,7 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Memory init ... ");
uint32_t kernel_blocks=mem_init(info);
- klog("Ram Filesystem init ... "); // required by mp.bin ????
+ klog("Ram Filesystem init ... ");
fs_mount(info);
// Start the other Processors (before paging because apic addr etc..?)
@@ -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);
@@ -69,7 +69,7 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Video Electronics Standards Association (VESA) init ... "); // TODO check if text or fb?
uint32_t addr=kballoc(1);
- fs_content("/binfont.bin",addr,0x100); // copy 0x100 bytes to 0x7000
+ fs_content("/binfont.bin",addr,0x100); // copy font (0x100 bytes) to memory.
vesa_init(info->vbe_control_info,info->vbe_mode_info,addr);
klog("stdin/stdout init ...");
@@ -82,5 +82,4 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Enable Interrupts & Start Scheduling ...");
scheduler_init(dir);
-
}
diff --git a/kernel/mem.c b/kernel/mem.c
index dea1284..8dfc6ea 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -1,13 +1,10 @@
-
-
#include <stdint.h>
-
#include "kernel.h"
#include "multiboot.h"
#define PMMNGR_BLOCKS_PER_BYTE 8
#define PMMNGR_BLOCK_SIZE 4096
-#define PMMNGR_MAX_BLOCKS 1048576
+#define PMMNGR_MAX_BLOCKS 1048576 // 4096*1048576 = 2^32 bytes (maxium addressable memory ~4GB)
#define PMMNGR_MAP_SIZE PMMNGR_MAX_BLOCKS/PMMNGR_BLOCKS_PER_BYTE/4
// defined in linker.ld and multiboot.s
@@ -18,7 +15,7 @@ extern uint32_t stack_bottom[];
//memory map bit array. Each bit represents a 4KB memory block,
//so uint32_t represents 8*4 blocks
-static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE];
+static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE]; //32Kb
static uint32_t mem_free_blocks; //number of free blocks
static uint32_t mem_max_block; //index of highest usable block
@@ -173,8 +170,8 @@ uint32_t mem_init(multiboot_information *info)
uint64_t mem_start=mmap->base_addr;
uint64_t mem_end=mmap->base_addr+mmap->length;
- klog("%08X - %08X / type: %s, (size: %d)",
- (uint32_t)mem_start, (uint32_t)mem_end, memmap_type_to_string[mmap->type-1], mmap->size);
+ klog("%08X - %08X (%d bytes)/ type: %s, (size: %d)",
+ (uint32_t)mem_start, (uint32_t)mem_end, (uint32_t)(mem_end-mem_start), memmap_type_to_string[mmap->type-1], mmap->size);
uint32_t mem=mmap->length;
@@ -204,25 +201,26 @@ uint32_t mem_init(multiboot_information *info)
mem_min_block=mod->mod_end/PMMNGR_BLOCK_SIZE+1;
- //pmmngr_deinit_region(mod->mod_start,((uint32_t)mod->mod_end-(uint32_t)mod->mod_start)+1);
+ pmmngr_deinit_region(mod->mod_start,((uint32_t)mod->mod_end-(uint32_t)mod->mod_start)+1);
mod++;
}
}
// deinitialize kernel
- //pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1);
+ pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1);
// we deinit everything below mem_min_block anyway
- pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE);
+ //pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE);
+
+ pmmngr_deinit_region(0,4096); // deinit first page (coz address=0 reserved for failure)
klog("Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024);
klog(
- "Free 4K blocks: %d (first free: 0x%08X)",mem_free_blocks,mem_min_block);
+ "Free 4K blocks: %d (first free: %d)",mem_free_blocks,mem_min_block);
return mem_min_block;
-
}
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 540e72b..b367825 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -2,7 +2,6 @@
//
//
-
#include "kernel.h"
#include "mem.h"
#include "asm/x86.h"
@@ -20,10 +19,17 @@ static volatile struct task_list_struct
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 waiting;
volatile bool skipwait;
volatile uint32_t brk;
volatile uint32_t esp0;
+
+ volatile bool syscall; // 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];
@@ -59,6 +65,36 @@ volatile int add_task(uint32_t esp, uint32_t vmem)
kpanic("out of task slots!");
}
+void task_wake_syscall_worker()
+{
+ task_list[2].waiting=false; // todo: context switch immiditly?
+}
+
+void task_syscall_worker()
+{
+ klog("checking if any pending syscalls.");
+
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ if(task_list[i].syscall)
+ {
+ 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);
+ syscall_generic(task_list[i].eax,
+ task_list[i].ebx,
+ task_list[i].ecx,
+ task_list[i].edx);
+
+ task_list[i].syscall=false;
+ }
+ }
+
+ task_list[current_task].waiting=true;
+ __asm__("hlt"); //TODO: force task switch here... via syscall?
+}
+
//
// REMEMBER WE ARE INSIDE AN INTERRUPT HERE - DON'T WASTE TIME!
//
@@ -83,10 +119,10 @@ volatile uint32_t my_scheduler(uint32_t oldesp)
{
int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style
- if(task_list[pid].active && !task_list[pid].waiting)
+ if(task_list[pid].active && !task_list[pid].waiting && !task_list[pid].syscall)
{
-// if(current_task!=pid)
-// klog("switch from %d to %d", current_task, pid);
+ if(current_task!=pid)
+ klog("switch from %d to %d", current_task, pid);
current_task=pid;
install_tss(task_list[pid].esp0);
@@ -108,6 +144,16 @@ volatile uint32_t task_switch_next(uint32_t oldesp)
return my_scheduler(oldesp);
}
+volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx,uint32_t oldesp)
+{
+ task_list[current_task].syscall=true;
+ task_list[current_task].eax=eax;
+ task_list[current_task].ebx=ebx;
+ task_list[current_task].ecx=ecx;
+ task_list[current_task].edx=edx;
+ return my_scheduler(oldesp);
+}
+
//TODO: free vmem too!
//TODO: notify waiting parent when child finished;
volatile uint32_t task_exit(uint32_t oldesp)
@@ -164,6 +210,11 @@ volatile uint32_t task_fork(uint32_t oldesp)
// init task (root of all other tasks / processes) //
volatile void scheduler_init(pdirectory *dir)
{
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ task_list[i].active=false;
+ }
+
current_task=0;
// this is our main user task on slot 0
@@ -181,6 +232,14 @@ volatile void scheduler_init(pdirectory *dir)
task_list[1].esp = kballoc(4)+4*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].vmem=dir;
+ task_list[2].esp = kballoc(4)+4*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[0].esp);
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 714acde..56c4ae8 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -11,6 +11,7 @@
#include <sys/time.h>
#include <stdbool.h>
#include <stddef.h>
+#include "syscalls.h"
// TODO: use includes!!!
uint64_t timer_get_ms();
@@ -26,9 +27,6 @@ term_out screen;
terminal_tty tty1;
-/// there also is task_fork, task_wait, task_exit.. which is in scheduler.c
-////////////////////////////////////////
-
int syscall_unhandled(int nr)
{
char msg[256];
@@ -334,3 +332,62 @@ int syscall_stat(const char *path, struct stat *st,int none)
st->st_mode = S_IFCHR;
return 0;
}
+
+/// 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)
+{
+
+ 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);
+ case SYSCALL_FORK :
+ return task_fork(p1,p2,p3);
+ 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);
+ }
+}
diff --git a/kernel/usermode.c b/kernel/usermode.c
index 1c039cb..3befefd 100644
--- a/kernel/usermode.c
+++ b/kernel/usermode.c
@@ -41,7 +41,7 @@ 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 TODO: switch to usermode before!
+ // if we are pid 0, replace ourselves with /bin/init and enter via usermode
if(task_get_current_pid()==0)
{
uint32_t alloc;
@@ -50,12 +50,21 @@ void userfunc()
usermode(entry_global);
}
- // kernel worker thread on pid1
+ // kernel worker thread: SLEEPER
if(task_get_current_pid()==1)
{
while(1)
{
- c1++;
+ __asm__("hlt");
+ }
+ }
+
+ // kernel worker thread: SYSCALL CHECKER
+ if(task_get_current_pid()==2)
+ {
+ while(1)
+ {
+ task_syscall_worker();
}
}
}
diff --git a/kernel/vmem.c b/kernel/vmem.c
index 55b9ca3..5bf530f 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -224,7 +224,7 @@ void vmem_free_dir(pdirectory *dir)
// programm pages procreates new programmspace
//
// TODO: FIX
-// KERNEL SPACE HARDCODED TO 5 first PAGES
+// KERNEL SPACE `kernel_pages` first PAGES
// FRAMEBUFER WE GET ON INIT
// PROGRAMM SPACE HARDCODED TO 0x8000000+2 pages and 0x8c00000+1 pages
//
@@ -390,10 +390,8 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir)
pt_entry_add_attrib (&page, I86_PTE_USER);
pt_entry_set_frame (&page, frame);
-
//! ...and add it to the page table
table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
-
}
pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
@@ -404,7 +402,6 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir)
pd_entry_set_frame (entry, (physical_addr)table);
virt_addr+=1024*4096;
-
}
// programm space
@@ -449,10 +446,8 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir)
pt_entry_add_attrib (&page, I86_PTE_USER);
pt_entry_set_frame (&page, frame);
-
//! ...and add it to the page table
table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
-
}
pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
diff --git a/kernel/vmem.h b/kernel/vmem.h
index ae1e134..b7e9cd3 100644
--- a/kernel/vmem.h
+++ b/kernel/vmem.h
@@ -12,7 +12,7 @@
//! directory table represents 4gb address space
#define DTABLE_ADDR_SPACE_SIZE 0x100000000
-//! page sizes are 4k
+//! page sizes are 4kb
#define PAGE_SIZE 4096
//! page table entry
@@ -21,10 +21,8 @@ typedef uint32_t pt_entry;
//! a page directery entry
typedef uint32_t pd_entry;
-
//! page table
typedef struct ptable_struct {
-
pt_entry m_entries[PAGES_PER_TABLE];
}ptable ;