Add stack frame to panic
This commit is contained in:
parent
b337e5193b
commit
cfcb806ebf
16 changed files with 169 additions and 103 deletions
9
Makefile
9
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
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "idt.h"
|
||||
#include "error.h"
|
||||
#include "smp.h"
|
||||
#include "timer.h"
|
||||
#include <kprint.h>
|
||||
#include <lock.h>
|
||||
|
|
@ -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("\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{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("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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <stddef.h>
|
||||
#include <kprint.h>
|
||||
#include <kmath.h>
|
||||
#include <string.h>
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
#include "error.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void _kmalloc_init(void);
|
||||
|
||||
void *kmalloc(uint64_t size);
|
||||
void *kmalloc(size_t size);
|
||||
void *kzalloc(size_t size);
|
||||
kstatus kfree(void *addr);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ struct ma_bufctl {
|
|||
struct ma_bufctl *next;
|
||||
size_t *startaddr;
|
||||
};
|
||||
|
||||
// ADD COLORING
|
||||
struct ma_slab {
|
||||
struct ma_kcache *cache;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(){
|
||||
for(;;){
|
||||
kprintf("Hello world from scheduled task!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void best_task(){
|
||||
for(;;){
|
||||
kprintf("Hello world I am best\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup a process structure */
|
||||
|
|
@ -36,12 +42,17 @@ 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;
|
||||
}
|
||||
|
|
@ -49,8 +60,10 @@ proc *alloc_process(void){
|
|||
|
||||
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));
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue