summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/interrupts.c5
-rw-r--r--kernel/kernel.c13
-rw-r--r--kernel/kernel.h2
-rw-r--r--kernel/scheduler.c182
-rw-r--r--kernel/scheduler.h15
-rw-r--r--kernel/syscalls.c73
-rw-r--r--kernel/syscalls.h1
-rw-r--r--kernel/vmem.c58
-rw-r--r--kernel/vmem.h1
9 files changed, 247 insertions, 103 deletions
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index 5e67105..9e12555 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -56,7 +56,10 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
// mouse and kb
if(irq==INTERRUPT_KEYBOARD || irq==INTERRUPT_MOUSE){
uint32_t in=x86_inb(0x60);
- if(irq==INTERRUPT_KEYBOARD)keyboard_handle(in); // do this in separate thread!
+ if(irq==INTERRUPT_KEYBOARD){
+ keyboard_handle(in); // do this in separate thread via syscalls?
+ task_wake_all();
+ }
// TODO: mouse
// test ipi
diff --git a/kernel/kernel.c b/kernel/kernel.c
index cf9fef9..6f04454 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -12,6 +12,7 @@
#include "vmem.h"
//-- clean below headers --//
+#include "ext2.h"
#include "apic.h"
#include "kernel/scheduler.h"
@@ -33,7 +34,6 @@
#include "driver/vesa.h"
#include "asm_pit.h"
-
/* F00L 0S Entry point (called directly from asm/multiboot.asm */
void kernel_main(uint32_t eax,uint32_t ebx)
{
@@ -91,6 +91,10 @@ void kernel_main(uint32_t eax,uint32_t ebx)
x86_set_page_directory(dir);
x86_paging_enable();
+ // -- EXT2 RAM IMAGE -- //
+ klog("Check ext2 ram image ... ");
+ ext2_dump_info(VMEM_EXT2_RAMIMAGE);
+
// -- APIC -- //
klog("Advanced Programmable Interrupt Controller (APIC) config ...");
apic_init(&cfg_acpi);
@@ -99,8 +103,11 @@ void kernel_main(uint32_t eax,uint32_t ebx)
// -- VESA -- //
fixme("tell terminal syscall somehow if we are vga or textmode");
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 font (0x100 bytes) to memory.
+
+ // binfont has to fit in ONE ext2 block //
+ fixme("support binfonts spanning multiple blocks?");
+ uint32_t inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,"/binfont.bin");
+ uint32_t addr= ext2_inode_blockstart( VMEM_EXT2_RAMIMAGE,inode,0);
vesa_init(cfg_multiboot->vbe_control_info,cfg_multiboot->vbe_mode_info,addr);
// -- STDIN/STDOUT -- //
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 3baef97..27798cf 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -54,6 +54,8 @@ REFERENCES
#define VMEM_KERNEL_END 0x02000000
#define VMEM_USER_ENV 0x07000000 // ? pages / per user process
+
+#define VMEM_USER_PROG_PAGES 256
#define VMEM_USER_PROG 0x08048000 // ? pages / per user process (usual entry: 0x8048080)
#define VMEM_USER_STACK_PAGES 4 // 4 pages / per thread
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 541eb15..3b50259 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -19,13 +19,13 @@
#define NO_TASK 0xffffffff
-static volatile uint32_t pid=1;
+static volatile uint32_t pid=1000;
-uint32_t nextPID()
+static uint32_t nextPID()
{
spinlock_spin(SPINLOCK_PID);
- uint32_t ret=pid;
pid++;
+ uint32_t ret=pid;
spinlock_release(SPINLOCK_PID);
return ret;
}
@@ -37,7 +37,7 @@ static volatile uint32_t current_task[SMP_MAX_PROC];
static volatile struct task_list_struct
{
volatile bool active; // is this slot used (Y/N)
- volatile uint32_t pid; // process id (TODO)
+ volatile uint32_t pid; // process id
volatile uint32_t parent; // parent process id
volatile uint32_t esp; // stack pointer of the task
@@ -46,11 +46,14 @@ static volatile struct task_list_struct
volatile uint32_t brk; // memory brk pos
- volatile bool wait; // waiting for syscall to be processed.
+ volatile bool try; // waiting coz syscall not processed yet
+ volatile bool syscall; // syscall in progress
volatile uint32_t eax;
volatile uint32_t ebx;
volatile uint32_t ecx;
volatile uint32_t edx;
+
+ volatile bool thread; // is this a light thread?
}task_list[SMP_MAX_PROC][MAX_TASKS];
@@ -70,7 +73,8 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][0].parent=0;
task_list[cpu][0].pid=nextPID();
task_list[cpu][0].active=true;
- task_list[cpu][0].wait=false;
+ task_list[cpu][0].syscall=false;
+ task_list[cpu][0].thread=false;
task_list[cpu][0].vmem=dir;
task_list[cpu][0].esp = VMEM_CPU_STACK_TOP-0x200;
task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks
@@ -81,7 +85,8 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][1].parent=0;
task_list[cpu][1].pid=nextPID();
task_list[cpu][1].active=true;
- task_list[cpu][1].wait=false;
+ task_list[cpu][0].thread=false;
+ task_list[cpu][1].syscall=false;
task_list[cpu][1].vmem=dir;
task_list[cpu][1].esp = kballoc(4)+4*4096-0x200; // 4 pages stack
task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
@@ -114,7 +119,7 @@ volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t force_pid)
{
int idx=(current_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style
- if(task_list[cpu][idx].active && !task_list[cpu][idx].wait) // find active non-blocked task
+ if(task_list[cpu][idx].active && !task_list[cpu][idx].syscall) // find active non-blocked task
{
//TODO: do NOT do this! deadlock imminent!
//if(cpu==0)klog("schedule %d->%d on cpu %d",current_task[cpu],idx,cpu );
@@ -136,13 +141,13 @@ void scheduler_func()
uint32_t cpu=smp_get(SMP_APIC_ID);
- if(task_get_current_pid()==0)
+ if(current_task[cpu]==0)
while(1)
{
task_syscall_worker();
}
- if(task_get_current_pid()==1)
+ if(current_task[cpu]==1)
while(1)
{
@@ -150,38 +155,36 @@ void scheduler_func()
{
uint32_t alloc;
uint32_t entry_global=load_elf(BIN_INIT,&alloc);
- task_set_brk(alloc);
+ task_set_brk(task_get_current_pid(),alloc);
asm_usermode(entry_global);
while(1);
}
}
}
-volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack)
+volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread)
{
+ uint32_t parent=task_runs(parent_pid);
uint32_t cpu=smp_get(SMP_APIC_ID);
- uint32_t *stk=task_list[cpu][pid].esp;
- stk[14]=entry;
- stk[17]=stack;
- return 1;
-}
-volatile int add_task(uint32_t parent,uint32_t vmem)
-{
- uint32_t cpu=smp_get(SMP_APIC_ID);
for(int i=0;i<MAX_TASKS;i++)
{
- if(task_list[cpu][i].active!=true)
+ if(task_list[cpu][i].active!=true) // find a free slot.
{
task_list[cpu][i].pid=nextPID();
+ task_list[cpu][i].parent=parent_pid;
+ task_list[cpu][i].thread=thread;
- task_list[cpu][i].parent=task_list[cpu][parent].pid;
task_list[cpu][i].vmem=vmem;
- task_list[cpu][i].esp = kballoc(4)+2*4096; // center
+ task_list[cpu][i].esp = kballoc(4)+2*4096; // center
task_list[cpu][i].esp0 = kballoc(4)+4*4096;
- task_list[cpu][i].wait=false;
- task_list[cpu][i].brk=task_list[cpu][current_task[cpu]].brk;
+
+ task_list[cpu][i].active=true; //TODO: LOCK! (also other similar)
+ task_list[cpu][i].syscall=false;
+ task_list[cpu][i].try=false;
+
+ task_list[cpu][i].brk=task_list[cpu][parent].brk;
uint32_t *source=(uint32_t *)task_list[cpu][parent].esp;
uint32_t *dst=(uint32_t *)task_list[cpu][i].esp;
@@ -197,13 +200,22 @@ volatile int add_task(uint32_t parent,uint32_t vmem)
stack[12]=0x1;
stack[13]=0; // this task returns pid=0 to the caller
- task_list[cpu][i].active=true; //TODO: LOCK! (also other similar)
- return i;
+ return task_list[cpu][i].pid;
}
}
kpanic("out of task slots!");
}
+void task_wake_all()
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ // simple approach, any syscall might unblock any other syscall // TODO: better! TODO: all cpus!
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ task_list[cpu][i].try=true;
+ }
+}
+
/**
* kernel space worker thread
@@ -211,40 +223,49 @@ volatile int add_task(uint32_t parent,uint32_t vmem)
* we can get interrupted by an interrupt ANYTIME!
*
*/
-
void task_syscall_worker()
{
+ /// TODO: cross check all cpus!
uint32_t cpu=smp_get(SMP_APIC_ID);
+
while(1)
{
- bool nowork=true;
for(int i=0;i<MAX_TASKS;i++)
{
- if(task_list[cpu][i].wait)
+ if(task_list[cpu][i].active,task_list[cpu][i].try&&task_list[cpu][i].syscall)
{
+
uint32_t syscall=task_list[cpu][i].eax;
- klog("task %d waiting on syscall %d/%s. processing...",i,syscall,syscall_get_name(syscall));
+ klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i);
+
task_list[cpu][0].vmem=task_list[cpu][i].vmem; // switch syscall worker to pagedir of calling userprog
x86_set_page_directory(task_list[cpu][0].vmem);
- nowork=false;
-
- uint32_t ret = syscall_generic(task_list[cpu][i].eax,
+ uint32_t ok = syscall_generic_test(task_list[cpu][i].eax,
task_list[cpu][i].edx,
task_list[cpu][i].ecx,
task_list[cpu][i].ebx,
- i);
+ task_list[cpu][i].pid);
- if(task_list[cpu][i].eax==SYSCALL_WAIT)
+ if(!ok)
{
+ task_list[cpu][i].try=false;
continue;
}
+ uint32_t ret = syscall_generic(task_list[cpu][i].eax,
+ task_list[cpu][i].edx,
+ task_list[cpu][i].ecx,
+ task_list[cpu][i].ebx,
+ task_list[cpu][i].pid);
+
+ task_wake_all();
+
uint32_t *stack=task_list[cpu][i].esp;
stack[12]=0x1;
stack[13]=ret;
- task_list[cpu][i].wait=false;
+ task_list[cpu][i].syscall=false;
}
}
@@ -254,48 +275,109 @@ void task_syscall_worker()
}
}
-
volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
- task_list[cpu][current_task[cpu]].wait=true;
+ task_list[cpu][current_task[cpu]].syscall=true;
+ task_list[cpu][current_task[cpu]].try=true;
task_list[cpu][current_task[cpu]].eax=eax;
task_list[cpu][current_task[cpu]].ebx=ebx;
task_list[cpu][current_task[cpu]].ecx=ecx;
task_list[cpu][current_task[cpu]].edx=edx;
- task_list[cpu][0].wait=false;
return 1;
}
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][pid].vmem,false));
- klog("[%d] forked -> [%d] (free blocks remaining: %d )", pid, ret,0);
+ int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,false),false);
+ klog("[%d] forked -> [%d]", pid, ret);
return ret;
}
+
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][pid].vmem,true));
- klog("[%d] cloned -> [%d] (free blocks remaining: %d )", pid, ret,0);
+ int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,true),true);
+ klog("[%d] cloned -> [%d]", pid, ret);
return ret;
}
-volatile int task_get_current_pid()
+volatile uint32_t task_get_brk(uint32_t pid)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
- return current_task[cpu];
+ uint32_t idx=task_idx(pid);
+ return task_list[cpu][idx].brk;
}
-volatile uint32_t task_get_brk()
+volatile void task_set_brk(uint32_t pid, uint32_t brk)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
- return task_list[cpu][current_task[cpu]].brk;
+ uint32_t idx=task_idx(pid);
+ task_list[cpu][idx].brk=brk;
}
-volatile void task_set_brk(uint32_t brk)
+volatile uint32_t task_get_current_pid()
{
uint32_t cpu=smp_get(SMP_APIC_ID);
- task_list[cpu][current_task[cpu]].brk=brk;
+ return task_list[cpu][current_task[cpu]].pid;
+}
+
+volatile uint32_t task_get_parent(uint32_t pid)
+{
+ uint32_t idx=task_idx(pid);
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ return task_list[cpu][idx].parent;
+}
+
+volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack,uint32_t brk)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ uint32_t idx=task_idx(pid);
+ uint32_t *stk=task_list[cpu][idx].esp;
+ task_list[cpu][idx].brk=brk;
+
+ stk[14]=entry;
+ stk[17]=stack;
+ return 1;
+}
+
+uint32_t task_idx(uint32_t pid)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ if(task_list[cpu][i].pid==pid)return i;
+ }
+
+ return 0;
+}
+
+uint32_t task_runs(uint32_t pid)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ if(task_list[cpu][i].active==true&& task_list[cpu][i].pid==pid)return i;
+ }
+
+ return 0;
+}
+
+void task_exit(uint32_t pid)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ uint32_t idx=task_runs(pid);
+
+ for(int i=0;i<MAX_TASKS;i++)
+ {
+ if(task_list[cpu][i].active==true&& task_list[cpu][i].pid==pid)
+ task_list[cpu][i].active=false;
+ }
+
+ vmem_free_space_dir(task_list[cpu][idx].vmem,false);
}
diff --git a/kernel/scheduler.h b/kernel/scheduler.h
index 18002da..f77912d 100644
--- a/kernel/scheduler.h
+++ b/kernel/scheduler.h
@@ -1,15 +1,20 @@
#include <stdint.h>
+#include <stdbool.h>
// http://hosted.cjmovie.net/TutMultitask.htm
volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t force_pid);
-volatile int task_get_current_pid();
-volatile void task_set_brk(uint32_t brk);
+void task_wake_all();
+volatile uint32_t task_get_current_pid();
+volatile uint32_t task_get_parent(uint32_t pid);
+volatile void task_set_brk(uint32_t pid,uint32_t brk);
void task_syscall_worker();
-volatile uint32_t task_get_brk();
-volatile uint32_t task_exit(uint32_t pid);
+volatile uint32_t task_get_brk(uint32_t pid);
volatile uint32_t task_fork(uint32_t pid);
volatile uint32_t task_clone(uint32_t pid);
volatile uint32_t task_wait(uint32_t pid);
-volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack);
+volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack, uint32_t brk);
volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx);
+uint32_t task_runs(uint32_t pid);
+uint32_t task_idx(uint32_t pid);
+void task_exit(uint32_t pid);
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 6707ec3..3fb813e 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -17,7 +17,6 @@
#include "scheduler.h"
#include "log.h"
-
// TODO: use includes!!!
uint64_t timer_get_ms();
@@ -134,20 +133,19 @@ int syscall_write(int file, char *buf, int len)
*/
int syscall_read(int file, char *buf, int len)
{
- //file 0 = stdin , file 1 = stdout , file 2 = stderr
- char c;
- int l=0;
-
- c=fd_read(&fds[file]);
- fifo_data_len[file]--;
- *buf=c;
- buf++;
- l++;
-
- return l;
- if(l==len)return l;
- if(c=='\n')return l;
-
+ //file 0 = stdin , file 1 = stdout , file 2 = stderr
+ char c;
+ int l=0;
+
+ c=fd_read(&fds[file]);
+ fifo_data_len[file]--;
+ *buf=c;
+ buf++;
+ l++;
+
+ return l;
+ if(l==len)return l;
+ if(c=='\n')return l;
}
//TODO: replace with dirent!
@@ -217,7 +215,6 @@ int copy_args(char **in, char **out)
int syscall_execve(char *name, char **argv, char **env,int pid)
{
-
//TODO copy environment to target pages somehow//
int arg_count=0;
while(argv[arg_count]!=NULL)arg_count++;
@@ -225,26 +222,23 @@ int syscall_execve(char *name, char **argv, char **env,int pid)
char **argv1=VMEM_USER_ENV;
if(argv!=NULL)
{
-// copy_args(argv,argv1);
+ copy_args(argv,argv1);
}
-
else{
argv1=NULL;
}
- char **env1=VMEM_USER_ENV+1024;
+ char **env1=VMEM_USER_ENV+1024*2;
if(env!=NULL)
{
-// copy_args(env,env1);
+ copy_args(env,env1);
}
-
else{
env1=NULL;
}
uint32_t alloc;
uint32_t entry_global=load_elf(name,&alloc);
- task_set_brk(alloc);
if(!entry_global)
{
@@ -255,7 +249,7 @@ int syscall_execve(char *name, char **argv, char **env,int pid)
*++stack=argv1;
*++stack=arg_count;
*++stack=env1;
- task_reset(pid,entry_global,stack);
+ task_reset(pid,entry_global,stack,alloc);
return 0;
/* try to move this to asm */
@@ -341,13 +335,13 @@ uint32_t syscall_clone(int pid)
uint32_t syscall_wait(int pid)
{
- fixme("implement syscall_wait");
return 0;
}
uint32_t syscall_exit(int pid)
{
fixme("free allll mem");
+ task_exit(pid);
return 0;
}
@@ -368,20 +362,15 @@ int syscall_isatty(int file,int none1,int none2)
return 1;
}
-uint32_t fuckalloc=0x8500000;
// TODO: per process basis!
-uint32_t syscall_sbrk(uint32_t incr, int none1, int none2)
+uint32_t syscall_sbrk(uint32_t incr, int none1, int none2, uint32_t pid)
{
- fixme("fake syscall_sbrk! 0x%08X",incr);
- uint32_t alloc=task_get_brk();
-
- uint32_t oldalloc=fuckalloc;
- fuckalloc+=incr;
-
- task_set_brk(alloc);
-
-
+ uint32_t alloc=task_get_brk(pid);
+ uint32_t oldalloc=alloc;
+ alloc+=incr;
+ task_set_brk(pid,alloc);
+ fixme("fake syscall_sbrk(0x%08X) return %08X",incr,oldalloc);
return oldalloc;
}
@@ -394,6 +383,18 @@ int syscall_stat(const char *path, struct stat *st,int none)
/// there also is task_fork, task_wait, task_exit.. which is in scheduler.c
////////////////////////////////////////
+uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+{
+ switch(nr){
+ case SYSCALL_WAIT :
+ return !task_runs(p1);
+ case SYSCALL_READ :
+ return p3 <= fifo_data_len[p1];
+ case SYSCALL_EXIT :
+ return 1;
+ }
+ return 1;
+}
uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
{
@@ -423,7 +424,7 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint
case SYSCALL_READ :
return syscall_read(p1,p2,p3);
case SYSCALL_SBRK :
- return syscall_sbrk(p1,p2,p3);
+ return syscall_sbrk(p1,p2,p3,pid);
case SYSCALL_STAT :
return syscall_stat(p1,p2,p3);
case SYSCALL_FSTAT :
diff --git a/kernel/syscalls.h b/kernel/syscalls.h
index b31d32c..b736519 100644
--- a/kernel/syscalls.h
+++ b/kernel/syscalls.h
@@ -27,6 +27,7 @@
char* syscall_get_name(uint32_t num);
uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid);
+uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid);
int syscall_open(char *name, int flags, int mode);
int syscall_write(int file, char *buf, int len);
diff --git a/kernel/vmem.c b/kernel/vmem.c
index 4faf93e..129ddb5 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -305,14 +305,46 @@ pdirectory* vmem_kernel_dir()
vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4,false);
vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*VMEM_CPU_STACK_PAGES,VMEM_CPU_STACK_PAGES,false);
- vmem_add_alloc(dir,VMEM_USER_PROG,1024*2,true);
- vmem_add_alloc(dir,VMEM_USER_ENV,2,true);
- vmem_add_alloc(dir,VMEM_USER_NEWLIB,2,true);
+ vmem_add_alloc(dir,VMEM_USER_PROG,VMEM_USER_PROG_PAGES,true);
+ vmem_add_alloc(dir,VMEM_USER_ENV,1,true);
+ vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true);
vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true);
return dir;
}
+void vmem_free_space_dir(pdirectory *dir,bool stack_only)
+{
+ fixme("free kmalloc too!");
+ fixme("stack_only version too!");
+
+ //free user pages
+ uint32_t virt=0;
+ for(int i=0;i<1024;i++)
+ {
+ uint32_t src_pt=dir->m_entries [i];
+
+ if(pt_entry_is_user(src_pt))
+ {
+ ptable *src_table=pt_entry_get_frame(&src_pt);
+
+ for(int j=0;j<1024;j++)
+ {
+ uint32_t src_pd=src_table->m_entries[j];
+ uint32_t src_phys=pd_entry_get_frame(&src_pd);
+
+ if(src_pd)
+ {
+ mem_free_block(src_phys);
+ }
+ virt+=4096;
+ }
+ }
+ else virt+=4096*1024;
+ }
+
+}
+
pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
{
pdirectory* dir = vmem_clean_dir(); //let's start with a fresh page directory
@@ -324,14 +356,25 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
if(!pt_entry_is_user(src_pt))dir->m_entries [i]=src_pt;
}
- vmem_add_alloc(dir,VMEM_USER_PROG,1024*4,true);
- vmem_add_alloc(dir,VMEM_USER_ENV,2,true);
- vmem_add_alloc(dir,VMEM_USER_NEWLIB,2,true);
+ // threads share this //
+ if(stack_only)
+ {
+ // TODO
+ kpanic("not impl!");
+ }
+ else
+ {
+ vmem_add_alloc(dir,VMEM_USER_PROG,VMEM_USER_PROG_PAGES,true);
+ vmem_add_alloc(dir,VMEM_USER_ENV,1,true);
+ }
+
+ // threads need own //
+ vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true);
vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true);
pdirectory* mydir=x86_get_page_directory();
- //copy user pages (TODO: stack only version for cloning!)
+ //copy user pages
uint32_t virt=0;
for(int i=0;i<1024;i++)
{
@@ -383,6 +426,5 @@ void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi)
multiboot_mod *mod=(multiboot_mod *)cfg_multiboot->mods_addr;
mod_start=mod->mod_start;
mod_end=mod->mod_end;
-
}
diff --git a/kernel/vmem.h b/kernel/vmem.h
index 767d7c5..c85d36b 100644
--- a/kernel/vmem.h
+++ b/kernel/vmem.h
@@ -56,5 +56,6 @@ struct pdirectory_struct;
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);
struct pdirectory_struct* vmem_kernel_dir();