diff --git a/Makefile b/Makefile index 333f92f..f820122 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,8 @@ CFLAGS += -Wall \ -I src/include \ -O0 \ -ggdb3 \ - -g + -g \ + #-fno-omit-frame-pointer CDEBUG = -g LDFLAGS += -m elf_x86_64 \ -nostdlib \ @@ -78,14 +79,12 @@ all: $(AS) src/scheduler/sched.asm -o $(BUILD_DIR)/sched_asm.o $(NASMFLAGS) - - # link everything to an elf - $(LD) -o $(BUILD_DIR)/SFB25.elf $(BUILD_DIR)/*.o $(LDFLAGS) + $(LD) -o $(BUILD_DIR)/Neobbo.elf $(BUILD_DIR)/*.o $(LDFLAGS) # Create a directory which will be our ISO root. mkdir -p iso_root # Copy the relevant files over. - cp -v $(BUILD_DIR)/SFB25.elf limine.conf limine/limine-bios.sys \ + cp -v $(BUILD_DIR)/Neobbo.elf limine.conf limine/limine-bios.sys \ limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/ # Create the EFI boot tree and copy Limine's EFI executables over. mkdir -p iso_root/EFI/BOOT diff --git a/src/hal/apic.c b/src/hal/apic.c index df8f28c..e95be34 100644 --- a/src/hal/apic.c +++ b/src/hal/apic.c @@ -126,10 +126,14 @@ void ap_apic_init(){ } void apic_timer_handler(){ + //kprintf("hii\n"); + lapic_write_reg(LAPIC_EOI_REG, 0); + if(get_cpu_struct_initialized()){ get_cpu_struct()->lapic_timer_ticks++; } + } void apic_send_ipi(uint8_t dest_field, uint8_t dest_shorthand, uint8_t trigger, uint8_t level, uint8_t status, uint8_t destination, uint8_t delivery_mode, uint8_t vector){ diff --git a/src/hal/idt.asm b/src/hal/idt.asm index cc84c13..3c3ee9b 100644 --- a/src/hal/idt.asm +++ b/src/hal/idt.asm @@ -2,6 +2,8 @@ default rel extern interrupt_handler +global next_frame + extern idtr global s_isr0 @@ -328,3 +330,7 @@ s_load_idt: sti ret +next_frame: + mov rax, [rdi] + ret + diff --git a/src/hal/idt.c b/src/hal/idt.c index f8957c0..a22ac0b 100644 --- a/src/hal/idt.c +++ b/src/hal/idt.c @@ -1,5 +1,6 @@ #include "idt.h" #include "error.h" +#include "smp.h" #include "timer.h" #include #include @@ -200,15 +201,30 @@ char *exception_messages[] = "Reserved" }; +extern void *next_frame(void *addr); + void interrupt_handler(interrupt_frame *r){ if(r->int_no < 32){ - kprintf("\nOh no! Received interrupt {d}, '{s}'. Below is the provided stack frame{n}{n}", r->int_no, exception_messages[r->int_no]); - kprintf("error code 0x{xn}", r->err); - kprintf("rax 0x{x} | rbx 0x{x} | rcx 0x{x} | rdx 0x{xn}", r->rax, r->rbx, r->rcx, r->rdx); - kprintf("rdi 0x{x} | rsi 0x{x} | rbp 0x{xn}", r->rdi, r->rsi, r->rbp); - kprintf("r8 0x{x} | r9 0x{x} | r10 0x{x} | r11 0x{x} | r12 0x{x} | r13 0x{x} | r14 0x{x} | r15 0x{xn}", r->r8, r->r9, r->r10, r->r11, r->r12, r->r13, r->r14, r->r15); - kprintf("rip 0x{x} | cs 0x{x} | ss 0x{x} | rsp 0x{x} | rflags 0x{xn}", r->rip, r->cs, r->ss, r->rsp, r->rflags); + kprintf("\nOh no! Received interrupt {d}, '{s}'. Below is the provided stack frame\n\n", r->int_no, exception_messages[r->int_no]); + + if(r->err != 0){ + kprintf("error code 0x{xn}", r->err); + } + kprintf("rax 0x{x} | rbx 0x{x} | rcx 0x{x} | rdx 0x{x}\n", r->rax, r->rbx, r->rcx, r->rdx); + kprintf("rdi 0x{x} | rsi 0x{x} | rbp 0x{x}\n", r->rdi, r->rsi, r->rbp); + kprintf("r8 0x{x} | r9 0x{x} | r10 0x{x} | r11 0x{x} | r12 0x{x} | r13 0x{x} | r14 0x{x} | r15 0x{x}\n", r->r8, r->r9, r->r10, r->r11, r->r12, r->r13, r->r14, r->r15); + kprintf("rip 0x{x} | cs 0x{x} | ss 0x{x} | rsp 0x{x} | rflags 0x{x}\n", r->rip, r->cs, r->ss, r->rsp, r->rflags); + + kprintf("\nStack frame:\n"); + struct stack_frame *f = __builtin_frame_address(0); + int i = 0; + while(f != NULL && i < 10){ + kprintf("{d}: 0x{x}\n", i, f->rip); + f = (stack_frame *)f->rbp; + i++; + } + kkill(); for(;;); } @@ -220,6 +236,12 @@ void interrupt_handler(interrupt_frame *r){ if(r->int_no == 69){ apic_timer_handler(); } + + if(r->int_no == 69 && get_cpu_struct_initialized() + && get_cpu_struct()->scheduler_initialized){ + enter_scheduler(); + } + if(r->int_no == 70){ for(;;){ asm("cli;hlt"); diff --git a/src/hal/idt.h b/src/hal/idt.h index 9b7e3a9..690df67 100644 --- a/src/hal/idt.h +++ b/src/hal/idt.h @@ -23,6 +23,11 @@ typedef struct interrupt_frame { uint64_t rip, cs, rflags, rsp, ss; } __attribute((packed)) interrupt_frame; +typedef struct stack_frame { + struct stack_frame *rbp; + uint64_t rip; +}__attribute((packed)) stack_frame; + typedef struct irq_t { void *base; bool in_use; diff --git a/src/hal/smp.c b/src/hal/smp.c index b884385..f3c65e4 100644 --- a/src/hal/smp.c +++ b/src/hal/smp.c @@ -65,6 +65,8 @@ void ap_init(struct limine_smp_info *smp_info){ memset(cpu_struct, 0, sizeof(cpu_state)); cpu_struct->lapic_id = smp_info->lapic_id; + cpu_struct->scheduler_context = (context*)kmalloc(sizeof(context)); + wrmsr(KERNELGSBASE, (uint64_t)cpu_struct); wrmsr(GSBASE, (uint64_t)cpu_struct); @@ -100,6 +102,8 @@ void smp_init(){ cpu_state *cpu_struct = (cpu_state*)kmalloc(sizeof(cpu_state)); cpu_struct->lapic_id = smp_response->cpus[0]->lapic_id; + cpu_struct->scheduler_context = (context*)kmalloc(sizeof(context)); + wrmsr(KERNELGSBASE, (uint64_t)cpu_struct); wrmsr(GSBASE, (uint64_t)cpu_struct); diff --git a/src/hal/smp.h b/src/hal/smp.h index 0c96151..8faf77f 100644 --- a/src/hal/smp.h +++ b/src/hal/smp.h @@ -13,8 +13,9 @@ typedef struct cpu_state { proc process_list[PROC_MAX]; proc *current_process; uint16_t process_count; - context scheduler_context; -}__attribute((packed))cpu_state; + context *scheduler_context; + bool scheduler_initialized; +}cpu_state; void smp_init(); cpu_state *get_cpu_struct(); diff --git a/src/lib/kprint.c b/src/lib/kprint.c index 0fa6f8e..09fd1ca 100644 --- a/src/lib/kprint.c +++ b/src/lib/kprint.c @@ -51,7 +51,7 @@ atomic_flag printf_lock = ATOMIC_FLAG_INIT; int kprintf(const char *format_string, ...){ extern struct flanterm_context *ft_ctx; - //acquire_spinlock(&printf_lock); + acquire_spinlock(&printf_lock); int state = NORMAL; va_list a_list; va_start(a_list, format_string); @@ -114,7 +114,7 @@ int kprintf(const char *format_string, ...){ } va_end(a_list); - //free_spinlock(&printf_lock); + free_spinlock(&printf_lock); return 0; } diff --git a/src/main.c b/src/main.c index 2407086..a03690b 100644 --- a/src/main.c +++ b/src/main.c @@ -84,6 +84,7 @@ void _start(void){ serial_init(); krand_init(); + set_gdt(); set_idt(); @@ -98,7 +99,6 @@ void _start(void){ klog("pmm", "Setting up the PMM"); pmm_init(); - klog("vmm", "Setting up the page tables"); vmm_init(); @@ -109,7 +109,6 @@ void _start(void){ klog("smp", "Starting APs"); smp_init(); - klog("pci", "Getting le pci"); pci_init(); diff --git a/src/mm/kmalloc.c b/src/mm/kmalloc.c index 52a65d5..952f050 100644 --- a/src/mm/kmalloc.c +++ b/src/mm/kmalloc.c @@ -2,6 +2,7 @@ #include #include #include +#include struct ma_kcache *kmalloc_caches[14] = {0}; // Create various sizes of caches to be used by kmalloc @@ -26,7 +27,7 @@ size_t sizes[14] = {16, 32, 64, 128, 256, 512, 1024, 4096, 8192, 32768, 65536, 1 void *kmalloc(size_t size){ if(size > 1048576){ - klog(__func__, "Attempted to allocate {d} bytes, more than max size (1M)"); + klog(__func__, "Attempted to allocate more than max size (1M)"); return NULL; } @@ -46,6 +47,15 @@ void *kmalloc(size_t size){ } +void *kzalloc(size_t size){ + void *addr = kmalloc(size); + if(addr == NULL){ + return NULL; + } + memset(addr, 0, size); + return addr; +} + kstatus kfree(void *addr){ return ma_cache_dealloc(addr); } \ No newline at end of file diff --git a/src/mm/kmalloc.h b/src/mm/kmalloc.h index c92a68f..b2607ae 100644 --- a/src/mm/kmalloc.h +++ b/src/mm/kmalloc.h @@ -1,7 +1,9 @@ #include "error.h" +#include #include void _kmalloc_init(void); -void *kmalloc(uint64_t size); +void *kmalloc(size_t size); +void *kzalloc(size_t size); kstatus kfree(void *addr); diff --git a/src/mm/slab.c b/src/mm/slab.c index 719d8f8..96cf711 100644 --- a/src/mm/slab.c +++ b/src/mm/slab.c @@ -113,6 +113,8 @@ kstatus _ma_alloc_slab(struct ma_kcache *kcache){ } } + //asm("int $1"); + if(kcache->slabs_free == NULL){ kcache->slabs_free = slab_structure; }else{ @@ -127,8 +129,10 @@ kstatus _ma_alloc_slab(struct ma_kcache *kcache){ return KERNEL_STATUS_SUCCESS; } - +// fix this complicated POS void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ + + struct ma_kcache *cache = slab->cache; struct ma_slab *sb = 0; switch (newstate) { @@ -199,6 +203,10 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ } free_common: + + slab->next = NULL; + slab->prev = NULL; + // Preserve the linkage if(sb->prev != NULL){ if(sb->next != NULL){ @@ -216,6 +224,10 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ return; partial_common: + + slab->next = NULL; + slab->prev = NULL; + if(sb->prev != NULL){ if(sb->next != NULL){ sb->next->prev = sb->prev; @@ -232,6 +244,9 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ return; used_common: + slab->next = NULL; + slab->prev = NULL; + if(sb->prev != NULL){ if(sb->next != NULL){ sb->next->prev = sb->prev; diff --git a/src/mm/slab.h b/src/mm/slab.h index 5526d33..41420d9 100644 --- a/src/mm/slab.h +++ b/src/mm/slab.h @@ -12,7 +12,7 @@ struct ma_bufctl { struct ma_bufctl *next; size_t *startaddr; }; - +// ADD COLORING struct ma_slab { struct ma_kcache *cache; diff --git a/src/scheduler/sched.asm b/src/scheduler/sched.asm index a874b8d..a66472c 100644 --- a/src/scheduler/sched.asm +++ b/src/scheduler/sched.asm @@ -3,59 +3,40 @@ global switch_context global get_context global restore_stack -; switch_context(struct context *old, struct context *new) +; switch_context(struct context **old, *struct context new) ; ^RDI ^RSI switch_context: - - pop r8 ; Fetch RIP from stack - - ; Save callee-saved registers to the old struct - mov [rdi + 0x00], rbx - mov [rdi + 0x08], rsp - mov [rdi + 0x10], rbp - mov [rdi + 0x18], r12 - mov [rdi + 0x20], r13 - mov [rdi + 0x28], r14 - mov [rdi + 0x30], r15 - mov [rdi + 0x38], r8 - - ; Load the new context - mov rbx, [rsi + 0x00] - mov rsp, [rsi + 0x08] - mov rbp, [rsi + 0x10] - mov r12, [rsi + 0x18] - mov r13, [rsi + 0x20] - mov r14, [rsi + 0x28] - mov r15, [rsi + 0x30] - + push rdi + push rsi + push rdx + push rcx + push rbx + push rbp push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 - jmp [rsi + 0x38] - - + mov [rdi], rsp + mov rsp, rsi + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rbx + pop rcx + pop rdx + pop rsi + pop rdi ret - -; get_context(struct context *ctx) -get_context: - pop r8 ; Fetch RIP from stack - - ; Save callee-saved registers to the old struct - mov [rdi + 0x00], rbx - mov [rdi + 0x08], rsp - mov [rdi + 0x10], rbp - mov [rdi + 0x18], r12 - mov [rdi + 0x20], r13 - mov [rdi + 0x28], r14 - mov [rdi + 0x30], r15 - mov [rdi + 0x38], r8 - - push r8 - - ret -; restore_stack(uint64_t rsp, uint64_t rbp) -restore_stack: - mov rsp, rdi - mov rbp, rsi - ret diff --git a/src/scheduler/sched.c b/src/scheduler/sched.c index 3125564..207622a 100644 --- a/src/scheduler/sched.c +++ b/src/scheduler/sched.c @@ -7,23 +7,29 @@ #include "../mm/kmalloc.h" #include "sched.h" -extern void get_context(struct context *ctx); +extern void switch_context(context **old, context *new); -extern void switch_context(context *old, context *new); - -extern void restore_stack(uint64_t rsp, uint64_t rbp); #define QUANTUM_US 10000 int next_pid = 1; void idle_task(){ - kprintf("Hello world from idle task!\n"); + for(;;){ + kprintf("Idle!!1\n"); + } } void test_task(){ - kprintf("Hello world from scheduled task!\n"); - return; + for(;;){ + kprintf("Hello world from scheduled task!\n"); + } +} + +void best_task(){ + for(;;){ + kprintf("Hello world I am best\n"); + } } /* Setup a process structure */ @@ -36,21 +42,28 @@ proc *alloc_process(void){ p->state = READY; - p->kstack = kmalloc(INITIAL_STACK_SIZE); + p->kstack = kzalloc(8 * 4096); p->pid = next_pid++; - p->context.rbp = (uint64_t)p->kstack; - p->context.rsp = (uint64_t)p->context.rbp + INITIAL_STACK_SIZE; - + uint64_t *sp = (uint64_t*)((uint64_t)p->kstack + 8 * 4096); + + // Allocate space for context + sp -= sizeof(context)/sizeof(uint64_t); + + p->context = (context*)sp; + p->context->rbp = (uint64_t)p->kstack; + return p; } } klog(__func__, "Couldnt find free process!!!!!!\n"); + return NULL; + } -proc *add_task(uint64_t *entry){ +proc *add_process(uint64_t *entry){ proc *proc = alloc_process(); if (proc == NULL) { @@ -58,29 +71,31 @@ proc *add_task(uint64_t *entry){ kkill(); } - proc->context.rip = (uint64_t)entry; + proc->context->rip = (uint64_t)entry; + + kprintf("entry: 0x{xn}", entry); return proc; } void scheduler_init(){ if(!get_cpu_struct_initialized()){ - kprintf("sched: cpu struct not initialized!"); + klog(__func__, "CPU struct not initialized!"); kkill(); } cpu_state *state = get_cpu_struct(); if(state->current_process != NULL){ - kprintf("sched: scheduler on CPU {d} already initialized!\n", state->lapic_id); - kkill(); + kprintf("scheduler on CPU {d} already initialized!\n", state->lapic_id); + return; } proc *proc_list = state->process_list; memset(proc_list, 0, sizeof(proc) * 512); - proc *idle = add_task((uint64_t*)idle_task); + proc *idle = add_process((uint64_t*)idle_task); if(idle == NULL){ klog(__func__, "Failed to allocate idle task"); @@ -89,27 +104,30 @@ void scheduler_init(){ state->current_process = idle; - add_task((uint64_t*)test_task); + add_process((uint64_t*)test_task); + + add_process((uint64_t *)best_task); + + state->scheduler_initialized = true; + + int i = 0; for(;;){ - for(int i = 0; i < PROC_MAX; i++){ + for(; i < PROC_MAX; i++){ if(proc_list[i].state == READY){ - - context old_state = state->current_process->context; - + proc *prev = state->current_process; + prev->state = READY; state->current_process = &proc_list[i]; state->current_process->state = RUNNING; + switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context); - get_context(&state->scheduler_context); - switch_context(&old_state, &state->current_process->context); } } + i = 1; } } -void scheduler_tick(){ - cpu_state *state = get_cpu_struct(); - proc *proc_list = state->process_list; - switch_context(&state->current_process->context, &state->scheduler_context); - +void enter_scheduler(){ + switch_context(&get_cpu_struct()->current_process->context, (get_cpu_struct()->scheduler_context)); + } \ No newline at end of file diff --git a/src/scheduler/sched.h b/src/scheduler/sched.h index f000c15..470e755 100644 --- a/src/scheduler/sched.h +++ b/src/scheduler/sched.h @@ -10,19 +10,19 @@ typedef enum proc_state { }proc_state; typedef struct context { - uint64_t rbx, rsp, rbp, r12, r13, r14, r15; - uint64_t rip; -} __attribute((packed))context; + uint64_t r15, r14, r13, r12, r11, r10, r9, r8, rbp, rbx, rcx, rdx, rsi, rdi, rip; +} context; typedef struct proc { uint64_t *mem; uint64_t *kstack; proc_state state; uint16_t pid; - context context; + context *context; }proc; void scheduler_init(); +void enter_scheduler(); #define PROC_MAX 512 // Max number of processes