From a3ee159ebfd2d088432e386e8809840784f697e7 Mon Sep 17 00:00:00 2001 From: Miguel Date: Wed, 12 Sep 2018 02:10:11 +0200 Subject: working on smp scheduler --- asm/asm_task.s | 4 +- asm/asm_usermode.s | 3 +- asm/asm_x86.h | 3 + kernel/interrupts.c | 12 +- kernel/kernel.h | 2 +- kernel/scheduler.c | 361 ++++++++++++++++++++++++++++------------------------ kernel/scheduler.h | 5 +- kernel/smp.c | 10 +- kernel/smp.h | 3 + kernel/vmem.c | 7 +- userspace/init.c | 2 + 11 files changed, 219 insertions(+), 193 deletions(-) diff --git a/asm/asm_task.s b/asm/asm_task.s index bf80025..77712ba 100644 --- a/asm/asm_task.s +++ b/asm/asm_task.s @@ -4,9 +4,9 @@ task_pusha: pushf push $0x8 // code segment - push $userfunc + push $scheduler_func - push $0x666 + push $0x666 // random value to hold place for potential return val push $0x0 pusha diff --git a/asm/asm_usermode.s b/asm/asm_usermode.s index 71ecc1d..147dfe5 100644 --- a/asm/asm_usermode.s +++ b/asm/asm_usermode.s @@ -20,7 +20,8 @@ asm_usermode: mov %esp, %eax pushl $0x23 // user data segment - pushl $0x8fff000-3*32 //%eax // current stack + //pushl $0x8fff000-3*32 //%eax // current stack + pushl $0xe0000000-3*32 //%eax // current stack (3 values will be poped) pushf // // http://x86.renejeschke.de/html/file_module_x86_id_145.html diff --git a/asm/asm_x86.h b/asm/asm_x86.h index 529a6c2..ec9ebd0 100644 --- a/asm/asm_x86.h +++ b/asm/asm_x86.h @@ -91,6 +91,9 @@ void x86_set_cr(uint8_t num, uint32_t value); /** Set the address of the page directory. This is required **before** enabling paging */ static inline void x86_set_page_directory(uint32_t pdir_addr) {x86_set_cr(3,pdir_addr);} +/** Get the address of the page directory. */ +static inline uint32_t x86_get_page_directory() {return x86_get_cr(3);} + /** Enable paging */ static inline void x86_paging_enable() {x86_set_cr(0,x86_get_cr(0)| 0x80000000);} diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 6e9d943..59d20c1 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -50,13 +50,7 @@ static void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) */ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { - // DO NOT WRITE INSIDE INTERRUPTS!! COZ IT ACQUIRES LOCK AND WE WILL DEADLOCK - // klog("int: %d on 0x%x",irq,apicID()); - if(irq==INTERRUPT_PIT_TIMER){ - asm_pit_tick(); -// asm_pit_sleep_40ms(); -// return esp; // tried to skip EOI - } + if(irq==INTERRUPT_PIT_TIMER)asm_pit_tick(); // mouse and kb if(irq==INTERRUPT_KEYBOARD || irq==INTERRUPT_MOUSE){ @@ -81,11 +75,11 @@ 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) + esp=scheduler_run(esp,2); // force scheduling of pid=2 (kernel worker) } // schedules on APIC timer 0x8C and IPI 0x81 - if(irq==INTERRUPT_APIC_TIMER || irq==INTERRUPT_IPI)esp=my_scheduler(esp,-1); // autoschedule + if(irq==INTERRUPT_APIC_TIMER || irq==INTERRUPT_IPI)esp=scheduler_run(esp,-1); // autoschedule if(irq!=INTERRUPT_SYSCALL)apic_eoi(); // ack all except software syscalls diff --git a/kernel/kernel.h b/kernel/kernel.h index e5c75f8..0010692 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -48,7 +48,7 @@ REFERENCES #define VMEM_KERNEL 0x00000000 // 8192 pages (32megs) / identity mapped #define VMEM_USER_ENV 0x07000000 // 4 pages / per user process -#define VMEM_USER_PROG 0x08000000 // ? pages / per user process (usual entry: 0x8048080) +#define VMEM_USER_PROG 0x08048000 // ? pages / per user process (usual entry: 0x8048080) #define VMEM_USER_STACK_TOP 0xE0000000 // ? pages / per thread #define VMEM_LAPIC 0xE0000000 // 1 pages / identity mapped diff --git a/kernel/scheduler.c b/kernel/scheduler.c index cac5ba7..d0b4b68 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -2,6 +2,7 @@ #include "kernel.h" #include "gdt.h" +#include "smp.h" #include "mem.h" #include "fs/elf.h" #include "asm_x86.h" @@ -16,9 +17,10 @@ #define NO_TASK 0xffffffff -static volatile uint32_t current_task=NO_TASK; +// we hold this stuff per cpu +static volatile uint32_t current_task[SMP_MAX_PROC]; -// TODO: per cpu! +// we hold this stuff per cpu static volatile struct task_list_struct { volatile bool active; // is this slot used (Y/N) @@ -37,11 +39,142 @@ static volatile struct task_list_struct volatile uint32_t ecx; volatile uint32_t edx; -}task_list[MAX_TASKS]; +}task_list[SMP_MAX_PROC][MAX_TASKS]; + +// init tasks // +volatile void scheduler_init(uint32_t cpu, void *dir) +{ + for(int i=0;i-1) - { - int pid=force_pid; - current_task=pid; - install_tss(0,task_list[pid].esp0); - - x86_set_page_directory(task_list[pid].vmem); - return task_list[pid].esp; - } - - for(int i=0;i [%d] (free blocks remaining: %d )", pid, ret,0); return ret; } volatile uint32_t task_clone(uint32_t pid) { + uint32_t cpu=smp_get(SMP_APIC_ID); //TODO: what will happen if we get rescheduled!?!?! - int ret=add_task(pid,vmem_new_space_dir(task_list[pid].vmem,true)); + 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); return ret; } -// init task (root of all other tasks / processes) // -volatile void scheduler_init(void *dir) -{ - for(int i=0;i // http://hosted.cjmovie.net/TutMultitask.htm -void scheduler_init(void *pdirectory_dir); + +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_syscall_worker(); @@ -11,4 +13,3 @@ 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 uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx); -volatile uint32_t my_scheduler(uint32_t oldesp,uint32_t force_pid); diff --git a/kernel/smp.c b/kernel/smp.c index d22fff0..52dd41a 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -69,15 +69,13 @@ static void run_smp() asm_smp_unlock(); - smp_set(0,apic_id()); - smp_set(1,'a'+apic_id()); + smp_set(SMP_APIC_ID,apic_id()); + smp_set(1000,'a'+apic_id()); + smp_set(SMP_SCHEDULER_INIT,1); x86_sti(); - while(1){ - syscall_write(1, VMEM_CPU_PRIVATE+4,1); // stdout - asm("hlt"); // wait for scheduler to kick in - } + while(1)asm("hlt"); // wait for scheduler to kick in } // this will start all our application processors! diff --git a/kernel/smp.h b/kernel/smp.h index a14f45c..862c903 100644 --- a/kernel/smp.h +++ b/kernel/smp.h @@ -12,6 +12,9 @@ #ifndef SMP_H #define SMP_H +#define SMP_APIC_ID 0 +#define SMP_SCHEDULER_INIT 1 + #include "acpi.h" void smp_start_aps(acpi_information *); diff --git a/kernel/vmem.c b/kernel/vmem.c index 3da35ce..c004f9e 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -243,7 +243,7 @@ static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_ if(alloc) { phys=mem_alloc_block(); // get free space from the memory manager - klog("allocated physical at 0x%08X",phys); +// klog("allocated physical at 0x%08X",phys); } //create a new page @@ -297,9 +297,11 @@ pdirectory* vmem_kernel_dir() vmem_add_remap(dir,mod_start,VMEM_EXT2_RAMIMAGE,1024*8);//32megs for ramimage: TODO: check if enough? vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4); - vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*4,4); + vmem_add_alloc(dir,VMEM_USER_PROG,1024*2); + vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*4,4); + return dir; } @@ -730,4 +732,3 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) x86_paging_enable(); return dir; } - diff --git a/userspace/init.c b/userspace/init.c index a82a597..163c9fd 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -4,6 +4,7 @@ int main(int argc, char **argv) { + char *argv1[]={"/bin/foolshell",0}; char *env1[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; @@ -13,6 +14,7 @@ int main(int argc, char **argv) printf("fool-init: spawning a Fool's Shell\n"); + while(1); // loop forever and spawn shells if the top-shell exits while(1) { -- cgit v1.2.3