summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-10-01 23:22:03 +0200
committerMiguel <m.i@gmx.at>2018-10-01 23:22:03 +0200
commita455cd5af26bf8731e7c981a9421b16ab34dae6f (patch)
tree140b184bf306cef258ba6e7965a78b3eecb598b9 /kernel
parentb518f39803eaaf0b25b95baf951b12ef4d5a727e (diff)
fukkin scheduler
Diffstat (limited to 'kernel')
-rw-r--r--kernel/apic.c2
-rw-r--r--kernel/kernel.c2
-rw-r--r--kernel/kernel.h2
-rw-r--r--kernel/ringbuffer.c14
-rw-r--r--kernel/ringbuffer.h3
-rw-r--r--kernel/scheduler.c57
-rw-r--r--kernel/scheduler.h2
-rw-r--r--kernel/smp.c2
-rw-r--r--kernel/syscalls.c18
-rw-r--r--kernel/syscalls.h3
-rw-r--r--kernel/vmem.c53
-rw-r--r--kernel/vmem.h1
12 files changed, 144 insertions, 15 deletions
diff --git a/kernel/apic.c b/kernel/apic.c
index 4bc2bb3..75837f7 100644
--- a/kernel/apic.c
+++ b/kernel/apic.c
@@ -156,7 +156,7 @@ void ioapic_config()
// ioapic_config_entry(2,0x90|0xa000,0x3<<24); // level trigger on low
// CPU
- ioapic_config_entry(2, INTERRUPT_PIT_TIMER, 0x0<<24); // pit
+// ioapic_config_entry(2, INTERRUPT_PIT_TIMER, 0x0<<24); // pit
ioapic_config_entry(1, INTERRUPT_KEYBOARD, 0x0<<24); // kb
ioapic_config_entry(12, INTERRUPT_MOUSE, 0x0<<24); // mouse
ioapic_config_entry(11, INTERRUPT_E1000|0x8000, 0x0<<24); // e1000 (level trigger on high)
diff --git a/kernel/kernel.c b/kernel/kernel.c
index f55b948..70b1913 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -155,7 +155,7 @@ void kernel_main(uint32_t eax,uint32_t ebx)
if(e1000_addr)
{
klog("E1000 init ...");
- e1000_init(e1000_addr);
+ // e1000_init(e1000_addr);
}
klog("Symmetric Multi Processing (SMP) start ... ");
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 1973d52..8ec8852 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -26,7 +26,7 @@ REFERENCES
#define VESA_MAX_HEIGHT 1080
//#define FOOLOS_UNIT_TESTING // Run Unit Tests
-//#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether)
+#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether)
//#define FOOLOS_COLORLESS // Turn off colors in log
#define HIDE_FIXME
diff --git a/kernel/ringbuffer.c b/kernel/ringbuffer.c
index 6700931..43d0e33 100644
--- a/kernel/ringbuffer.c
+++ b/kernel/ringbuffer.c
@@ -18,10 +18,7 @@ void ringbuffer_free(ringbuffer *f)
bool ringbuffer_put(ringbuffer* f,uint8_t c)
{
- if((f->back-1+f->size)%f->size==f->front)
- {
- return false;
- }
+ if(ringbuffer_full(f))return false;
f->data[f->back]=c;
f->back--;
@@ -30,6 +27,15 @@ bool ringbuffer_put(ringbuffer* f,uint8_t c)
return true;
}
+bool ringbuffer_full(ringbuffer* f)
+{
+ if((f->back-1+f->size)%f->size==f->front)
+ {
+ return true;
+ }
+ return false;
+}
+
bool ringbuffer_has(ringbuffer* f)
{
bool res=true;
diff --git a/kernel/ringbuffer.h b/kernel/ringbuffer.h
index 1ec88c8..6ad9537 100644
--- a/kernel/ringbuffer.h
+++ b/kernel/ringbuffer.h
@@ -53,4 +53,7 @@ uint8_t ringbuffer_get(ringbuffer*);
/** Check if buffer is not empty */
bool ringbuffer_has(ringbuffer*);
+/** Check if buffer is full */
+bool ringbuffer_full(ringbuffer* f);
+
#endif
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index fa32ebc..a4e3743 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -20,6 +20,7 @@
#include "mouse.h"
#include "syscalls.h"
#include "fs/ext2.h"
+#include "lib/string/string.h"
#define NO_TASK 0xffffffff
@@ -59,6 +60,8 @@ static volatile struct task_list_struct
volatile uint32_t edx;
volatile bool thread; // is this a light thread?
+
+ volatile char name[255];
}task_list[SMP_MAX_PROC][MAX_TASKS];
@@ -84,6 +87,7 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][0].vmem=dir;
task_list[cpu][0].esp = VMEM_CPU_STACK_TOP-0x200-8;
task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks
+ strcpy(task_list[cpu][0].name,"kernel_worker");
fd_init_std_streams(task_list[cpu][0].pid,0);
// this will go to userspace
@@ -95,6 +99,7 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][1].vmem=dir;
task_list[cpu][1].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
+ strcpy(task_list[cpu][1].name,"init");
fd_init_std_streams(task_list[cpu][1].pid,0);
@@ -107,6 +112,7 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][2].vmem=dir;
task_list[cpu][2].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign
task_list[cpu][2].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
+ strcpy(task_list[cpu][2].name,"idle process");
fd_init_std_streams(task_list[cpu][2].pid,0);
// stacks
@@ -117,14 +123,21 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
static uint32_t scheduler_schedule(uint32_t idx)
{
+
uint32_t cpu=smp_get(SMP_APIC_ID);
+
if(task_list[cpu][idx].active && !task_list[cpu][idx].syscall)
{
if(current_task[cpu]!=0)last_task[cpu]=current_task[cpu];
+ if(current_task[cpu]==idx)return task_list[cpu][idx].esp;
+
current_task[cpu]=idx;
- klog("%d",idx);
- // klog("%d idx %d",last_task[cpu],current_task[cpu]);
+ //klog("idx %d",idx);
+ //klog("name: %s",task_list[cpu][idx].name);
+
+ //klog("cpu %d / idx %d / pid %d / name: %5s",cpu,idx,task_list[cpu][idx].pid,task_list[cpu][idx].name);
+ //klog("%d idx %d",last_task[cpu],current_task[cpu]);
install_tss(cpu,task_list[cpu][idx].esp0);
x86_set_page_directory(task_list[cpu][idx].vmem);
@@ -211,7 +224,10 @@ void scheduler_func()
if(current_task[cpu]==2)
while(1)
{
- while(1)asm("hlt"); // sleeper task
+ uint64_t t0=x86_rdtscp();
+ asm("hlt"); // sleeper task
+ uint64_t t1=x86_rdtscp();
+ klog("slept: l:%d h:%d",(t1-t0));
}
if(current_task[cpu]==1)
@@ -274,6 +290,8 @@ volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread, char *name
first=false;
}
+ strcpy(task_list[cpu][i].name,name);
+
return task_list[cpu][i].pid;
}
}
@@ -306,22 +324,27 @@ void scheduler_wake_all()
*/
void task_syscall_worker()
{
+ static uint32_t c=0;
/// TODO: cross check all cpus!
uint32_t cpu=smp_get(SMP_APIC_ID);
while(1)
{
bool wake=false;
+ bool wake_mouse=false;
//TODO: would be enough only to lock during ringbuffer acces!?
x86_cli(); // disable temporarily mouse/kb/timer interrupts.
wake|=keyboard_worker();
- wake|=mouse_worker();
+ wake_mouse|=mouse_worker();
x86_sti();
+ if(wake_mouse)compositor_swap_buffers();
+
if(wake)scheduler_wake_all();
- if(cpu==0)compositor_swap_buffers();
+
+ //if(cpu==0)compositor_swap_buffers();
for(int i=0;i<MAX_TASKS;i++)
{
@@ -405,16 +428,25 @@ volatile uint32_t task_fork(uint32_t pid)
{
uint32_t idx=task_runs(pid);
uint32_t cpu=smp_get(SMP_APIC_ID);
- int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,false),false);
+ char *name=task_list[cpu][idx].name;
+ int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,false),false,name);
klog("[%d] forked -> [%d]", pid, ret);
return ret;
}
+void task_set_name(uint32_t pid, char *name)
+{
+ uint32_t idx=task_runs(pid);
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ strcpy(task_list[cpu][idx].name,name);
+}
+
volatile uint32_t task_clone(uint32_t pid)
{
uint32_t idx=task_runs(pid);
uint32_t cpu=smp_get(SMP_APIC_ID);
- int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,true),true);
+ char *name=task_list[cpu][idx].name;
+ int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,true),true,name);
klog("[%d] cloned -> [%d]", pid, ret);
return ret;
}
@@ -446,6 +478,17 @@ volatile uint32_t task_get_parent(uint32_t pid)
return task_list[cpu][idx].parent;
}
+volatile int task_add_win(uint32_t pid)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ uint32_t idx=task_idx(pid);
+
+ struct pdirectory *vmem=task_list[cpu][idx].vmem;
+ vmem_add_framebuffer(vmem);
+ compositor_add_window(vmem);
+ return 0;
+}
+
volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack,uint32_t brk)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
diff --git a/kernel/scheduler.h b/kernel/scheduler.h
index 1911bc6..71d5646 100644
--- a/kernel/scheduler.h
+++ b/kernel/scheduler.h
@@ -19,3 +19,5 @@ volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t
uint32_t task_runs(uint32_t pid);
uint32_t task_idx(uint32_t pid);
void task_exit(uint32_t pid);
+void task_set_name(uint32_t pid, char *name);
+volatile int task_add_win(uint32_t pid);
diff --git a/kernel/smp.c b/kernel/smp.c
index 0438db8..01230cf 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -58,7 +58,7 @@ void run_smp()
apic_enable();
klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id());
- apic_init_timer(100);// freq x HZ
+ apic_init_timer(3);// freq x HZ
klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id());
asm_smp_unlock();
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 5bdb76e..3b97917 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -22,6 +22,7 @@
#include "mem.h"
#include "reent.h"
#include "errno.h"
+#include "compositor.h"
#include "stdstreams.h"
#define MAX_PID 200
@@ -237,6 +238,7 @@ int copy_args(char **in, char **out)
int syscall_execve(const char *name, char *const argv[], char *const env[], int pid)
{
+
fixme("not overwrite yourself?");
int arg_count=0;
while(argv[arg_count]!=NULL)arg_count++;
@@ -262,6 +264,8 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int
*--stack=arg_count;
*--stack=env1;
task_reset(pid,entry_global,stack,alloc);
+ task_set_name(pid,name);
+
return 0;
}
@@ -398,6 +402,16 @@ uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid)
fds[pid][newfd]=fd_dupl(&fds[pid][oldfd]);
return newfd;
}
+uint32_t syscall_gui_rect(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+{
+ compositor_swap_buffers();
+ return 1;
+}
+uint32_t syscall_gui_win(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+{
+ task_add_win(pid);
+ return 1;
+}
/** Generics */
uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
@@ -469,6 +483,10 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint
return syscall_pipe(p1,p2,p3,pid);
case SYSCALL_DUP2 :
return syscall_dup2(p1,p2,p3,pid);
+ case SYSCALL_GUI_RECT :
+ return syscall_gui_rect(p1,p2,p3,pid);
+ case SYSCALL_GUI_WIN :
+ return syscall_gui_win(p1,p2,p3,pid);
}
kpanic("unknown syscall %d",nr);
}
diff --git a/kernel/syscalls.h b/kernel/syscalls.h
index 5403c2c..f77aea5 100644
--- a/kernel/syscalls.h
+++ b/kernel/syscalls.h
@@ -42,6 +42,9 @@
#define SYSCALL_PIPE 84
#define SYSCALL_DUP2 86
+#define SYSCALL_GUI_RECT 87
+#define SYSCALL_GUI_WIN 88
+
/** Todo move somewhere else and init per process , think how to make thread safe */
void fd_init_std_streams(uint32_t pid, bool use_framebuffer);
diff --git a/kernel/vmem.c b/kernel/vmem.c
index a1ee0e2..d99f6fd 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -212,6 +212,53 @@ static void vmem_clear_one(pdirectory* dir,uint32_t virt)
}
}
+
+// addresses need to be page aligned. (or will be forced down)
+static void vmem_del_generic(pdirectory* dir, uint32_t virt,uint32_t pages, bool dealloc, bool user)
+{
+ //fixme("make sure the pages are marked as used in the physical mem manager, really?");
+
+ //force align
+ virt/=4096;
+ virt*=4096;
+
+ while(pages>0)
+ {
+ pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt) ];
+ ptable* table;
+
+ if(*entry==0){
+ // no pagetable here yet.
+ kpanic("no pagetable found for vmem entry to delete!");
+ }
+ else{
+ // we use the existing one.
+ table= pd_entry_get_frame (entry);
+ }
+
+ if(dealloc)
+ {
+ uint32_t page=table->m_entries [PAGE_TABLE_INDEX (virt) ];
+ uint32_t phys=pt_entry_get_frame(page);
+ mem_free_block(phys); // free the space
+ }
+
+ //zero page
+ pt_entry page=0;
+
+ //set the page table
+ uint32_t old=table->m_entries [PAGE_TABLE_INDEX (virt) ];
+
+ if(old==0)kpanic("nothing to delete in vmem at 0x%08x",virt);
+
+ table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
+
+ virt+=4096;
+
+ pages--;
+ }
+}
+
// addresses need to be page aligned. (or will be forced down)
static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages, bool alloc, bool user)
{
@@ -317,6 +364,12 @@ pdirectory* vmem_kernel_dir()
return dir;
}
+void vmem_add_framebuffer(pdirectory *dir)
+{
+ vmem_del_generic(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,false, true);
+ vmem_add_alloc(dir, VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area
+}
+
void vmem_free_space_dir(pdirectory *dir,bool stack_only)
{
diff --git a/kernel/vmem.h b/kernel/vmem.h
index 211b5d3..73f9ce6 100644
--- a/kernel/vmem.h
+++ b/kernel/vmem.h
@@ -57,5 +57,6 @@ void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi,
void vmem_free_dir(struct pdirectory_struct *dir);
struct pdirectory_struct* vmem_new_space_dir(struct pdirectory_struct *copy_dir,bool stack_only);
void vmem_free_space_dir(struct pdirectory_struct *dir,bool stack_only);
+void vmem_add_framebuffer(struct pdirectory_struct *dir);
struct pdirectory_struct* vmem_kernel_dir();