diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/interrupts.c | 24 | ||||
| -rw-r--r-- | kernel/kernel.c | 7 | ||||
| -rw-r--r-- | kernel/mem.c | 22 | ||||
| -rw-r--r-- | kernel/scheduler.c | 69 | ||||
| -rw-r--r-- | kernel/syscalls.c | 63 | ||||
| -rw-r--r-- | kernel/usermode.c | 15 | ||||
| -rw-r--r-- | kernel/vmem.c | 7 | ||||
| -rw-r--r-- | kernel/vmem.h | 4 |
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 ; |
