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 \
|
-I src/include \
|
||||||
-O0 \
|
-O0 \
|
||||||
-ggdb3 \
|
-ggdb3 \
|
||||||
-g
|
-g \
|
||||||
|
#-fno-omit-frame-pointer
|
||||||
CDEBUG = -g
|
CDEBUG = -g
|
||||||
LDFLAGS += -m elf_x86_64 \
|
LDFLAGS += -m elf_x86_64 \
|
||||||
-nostdlib \
|
-nostdlib \
|
||||||
|
|
@ -78,14 +79,12 @@ all:
|
||||||
$(AS) src/scheduler/sched.asm -o $(BUILD_DIR)/sched_asm.o $(NASMFLAGS)
|
$(AS) src/scheduler/sched.asm -o $(BUILD_DIR)/sched_asm.o $(NASMFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# link everything to an elf
|
# 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.
|
# Create a directory which will be our ISO root.
|
||||||
mkdir -p iso_root
|
mkdir -p iso_root
|
||||||
# Copy the relevant files over.
|
# 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/
|
limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/
|
||||||
# Create the EFI boot tree and copy Limine's EFI executables over.
|
# Create the EFI boot tree and copy Limine's EFI executables over.
|
||||||
mkdir -p iso_root/EFI/BOOT
|
mkdir -p iso_root/EFI/BOOT
|
||||||
|
|
|
||||||
|
|
@ -126,10 +126,14 @@ void ap_apic_init(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void apic_timer_handler(){
|
void apic_timer_handler(){
|
||||||
|
//kprintf("hii\n");
|
||||||
|
|
||||||
lapic_write_reg(LAPIC_EOI_REG, 0);
|
lapic_write_reg(LAPIC_EOI_REG, 0);
|
||||||
|
|
||||||
if(get_cpu_struct_initialized()){
|
if(get_cpu_struct_initialized()){
|
||||||
get_cpu_struct()->lapic_timer_ticks++;
|
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){
|
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
|
extern interrupt_handler
|
||||||
|
|
||||||
|
global next_frame
|
||||||
|
|
||||||
extern idtr
|
extern idtr
|
||||||
|
|
||||||
global s_isr0
|
global s_isr0
|
||||||
|
|
@ -328,3 +330,7 @@ s_load_idt:
|
||||||
sti
|
sti
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
next_frame:
|
||||||
|
mov rax, [rdi]
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "smp.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include <kprint.h>
|
#include <kprint.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
@ -200,15 +201,30 @@ char *exception_messages[] =
|
||||||
"Reserved"
|
"Reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void *next_frame(void *addr);
|
||||||
|
|
||||||
void interrupt_handler(interrupt_frame *r){
|
void interrupt_handler(interrupt_frame *r){
|
||||||
|
|
||||||
if(r->int_no < 32){
|
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("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("rax 0x{x} | rbx 0x{x} | rcx 0x{x} | rdx 0x{x}\n", r->rax, r->rbx, r->rcx, r->rdx);
|
||||||
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("rdi 0x{x} | rsi 0x{x} | rbp 0x{x}\n", r->rdi, r->rsi, r->rbp);
|
||||||
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("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();
|
kkill();
|
||||||
for(;;);
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
@ -220,6 +236,12 @@ void interrupt_handler(interrupt_frame *r){
|
||||||
if(r->int_no == 69){
|
if(r->int_no == 69){
|
||||||
apic_timer_handler();
|
apic_timer_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(r->int_no == 69 && get_cpu_struct_initialized()
|
||||||
|
&& get_cpu_struct()->scheduler_initialized){
|
||||||
|
enter_scheduler();
|
||||||
|
}
|
||||||
|
|
||||||
if(r->int_no == 70){
|
if(r->int_no == 70){
|
||||||
for(;;){
|
for(;;){
|
||||||
asm("cli;hlt");
|
asm("cli;hlt");
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ typedef struct interrupt_frame {
|
||||||
uint64_t rip, cs, rflags, rsp, ss;
|
uint64_t rip, cs, rflags, rsp, ss;
|
||||||
} __attribute((packed)) interrupt_frame;
|
} __attribute((packed)) interrupt_frame;
|
||||||
|
|
||||||
|
typedef struct stack_frame {
|
||||||
|
struct stack_frame *rbp;
|
||||||
|
uint64_t rip;
|
||||||
|
}__attribute((packed)) stack_frame;
|
||||||
|
|
||||||
typedef struct irq_t {
|
typedef struct irq_t {
|
||||||
void *base;
|
void *base;
|
||||||
bool in_use;
|
bool in_use;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ void ap_init(struct limine_smp_info *smp_info){
|
||||||
memset(cpu_struct, 0, sizeof(cpu_state));
|
memset(cpu_struct, 0, sizeof(cpu_state));
|
||||||
cpu_struct->lapic_id = smp_info->lapic_id;
|
cpu_struct->lapic_id = smp_info->lapic_id;
|
||||||
|
|
||||||
|
cpu_struct->scheduler_context = (context*)kmalloc(sizeof(context));
|
||||||
|
|
||||||
wrmsr(KERNELGSBASE, (uint64_t)cpu_struct);
|
wrmsr(KERNELGSBASE, (uint64_t)cpu_struct);
|
||||||
wrmsr(GSBASE, (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_state *cpu_struct = (cpu_state*)kmalloc(sizeof(cpu_state));
|
||||||
cpu_struct->lapic_id = smp_response->cpus[0]->lapic_id;
|
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(KERNELGSBASE, (uint64_t)cpu_struct);
|
||||||
wrmsr(GSBASE, (uint64_t)cpu_struct);
|
wrmsr(GSBASE, (uint64_t)cpu_struct);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ typedef struct cpu_state {
|
||||||
proc process_list[PROC_MAX];
|
proc process_list[PROC_MAX];
|
||||||
proc *current_process;
|
proc *current_process;
|
||||||
uint16_t process_count;
|
uint16_t process_count;
|
||||||
context scheduler_context;
|
context *scheduler_context;
|
||||||
}__attribute((packed))cpu_state;
|
bool scheduler_initialized;
|
||||||
|
}cpu_state;
|
||||||
|
|
||||||
void smp_init();
|
void smp_init();
|
||||||
cpu_state *get_cpu_struct();
|
cpu_state *get_cpu_struct();
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ atomic_flag printf_lock = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
int kprintf(const char *format_string, ...){
|
int kprintf(const char *format_string, ...){
|
||||||
extern struct flanterm_context *ft_ctx;
|
extern struct flanterm_context *ft_ctx;
|
||||||
//acquire_spinlock(&printf_lock);
|
acquire_spinlock(&printf_lock);
|
||||||
int state = NORMAL;
|
int state = NORMAL;
|
||||||
va_list a_list;
|
va_list a_list;
|
||||||
va_start(a_list, format_string);
|
va_start(a_list, format_string);
|
||||||
|
|
@ -114,7 +114,7 @@ int kprintf(const char *format_string, ...){
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(a_list);
|
va_end(a_list);
|
||||||
//free_spinlock(&printf_lock);
|
free_spinlock(&printf_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ void _start(void){
|
||||||
|
|
||||||
serial_init();
|
serial_init();
|
||||||
krand_init();
|
krand_init();
|
||||||
|
|
||||||
set_gdt();
|
set_gdt();
|
||||||
set_idt();
|
set_idt();
|
||||||
|
|
||||||
|
|
@ -98,7 +99,6 @@ void _start(void){
|
||||||
klog("pmm", "Setting up the PMM");
|
klog("pmm", "Setting up the PMM");
|
||||||
pmm_init();
|
pmm_init();
|
||||||
|
|
||||||
|
|
||||||
klog("vmm", "Setting up the page tables");
|
klog("vmm", "Setting up the page tables");
|
||||||
vmm_init();
|
vmm_init();
|
||||||
|
|
||||||
|
|
@ -109,7 +109,6 @@ void _start(void){
|
||||||
klog("smp", "Starting APs");
|
klog("smp", "Starting APs");
|
||||||
smp_init();
|
smp_init();
|
||||||
|
|
||||||
|
|
||||||
klog("pci", "Getting le pci");
|
klog("pci", "Getting le pci");
|
||||||
pci_init();
|
pci_init();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <kprint.h>
|
#include <kprint.h>
|
||||||
#include <kmath.h>
|
#include <kmath.h>
|
||||||
|
#include <string.h>
|
||||||
struct ma_kcache *kmalloc_caches[14] = {0};
|
struct ma_kcache *kmalloc_caches[14] = {0};
|
||||||
|
|
||||||
// Create various sizes of caches to be used by kmalloc
|
// 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){
|
void *kmalloc(size_t size){
|
||||||
if(size > 1048576){
|
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;
|
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){
|
kstatus kfree(void *addr){
|
||||||
return ma_cache_dealloc(addr);
|
return ma_cache_dealloc(addr);
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void _kmalloc_init(void);
|
void _kmalloc_init(void);
|
||||||
|
|
||||||
void *kmalloc(uint64_t size);
|
void *kmalloc(size_t size);
|
||||||
|
void *kzalloc(size_t size);
|
||||||
kstatus kfree(void *addr);
|
kstatus kfree(void *addr);
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,8 @@ kstatus _ma_alloc_slab(struct ma_kcache *kcache){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//asm("int $1");
|
||||||
|
|
||||||
if(kcache->slabs_free == NULL){
|
if(kcache->slabs_free == NULL){
|
||||||
kcache->slabs_free = slab_structure;
|
kcache->slabs_free = slab_structure;
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -127,8 +129,10 @@ kstatus _ma_alloc_slab(struct ma_kcache *kcache){
|
||||||
return KERNEL_STATUS_SUCCESS;
|
return KERNEL_STATUS_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// fix this complicated POS
|
||||||
void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
||||||
|
|
||||||
|
|
||||||
struct ma_kcache *cache = slab->cache;
|
struct ma_kcache *cache = slab->cache;
|
||||||
struct ma_slab *sb = 0;
|
struct ma_slab *sb = 0;
|
||||||
switch (newstate) {
|
switch (newstate) {
|
||||||
|
|
@ -199,6 +203,10 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
||||||
}
|
}
|
||||||
|
|
||||||
free_common:
|
free_common:
|
||||||
|
|
||||||
|
slab->next = NULL;
|
||||||
|
slab->prev = NULL;
|
||||||
|
|
||||||
// Preserve the linkage
|
// Preserve the linkage
|
||||||
if(sb->prev != NULL){
|
if(sb->prev != NULL){
|
||||||
if(sb->next != NULL){
|
if(sb->next != NULL){
|
||||||
|
|
@ -216,6 +224,10 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
||||||
|
|
||||||
return;
|
return;
|
||||||
partial_common:
|
partial_common:
|
||||||
|
|
||||||
|
slab->next = NULL;
|
||||||
|
slab->prev = NULL;
|
||||||
|
|
||||||
if(sb->prev != NULL){
|
if(sb->prev != NULL){
|
||||||
if(sb->next != NULL){
|
if(sb->next != NULL){
|
||||||
sb->next->prev = sb->prev;
|
sb->next->prev = sb->prev;
|
||||||
|
|
@ -232,6 +244,9 @@ void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
||||||
|
|
||||||
return;
|
return;
|
||||||
used_common:
|
used_common:
|
||||||
|
slab->next = NULL;
|
||||||
|
slab->prev = NULL;
|
||||||
|
|
||||||
if(sb->prev != NULL){
|
if(sb->prev != NULL){
|
||||||
if(sb->next != NULL){
|
if(sb->next != NULL){
|
||||||
sb->next->prev = sb->prev;
|
sb->next->prev = sb->prev;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ struct ma_bufctl {
|
||||||
struct ma_bufctl *next;
|
struct ma_bufctl *next;
|
||||||
size_t *startaddr;
|
size_t *startaddr;
|
||||||
};
|
};
|
||||||
|
// ADD COLORING
|
||||||
struct ma_slab {
|
struct ma_slab {
|
||||||
struct ma_kcache *cache;
|
struct ma_kcache *cache;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,59 +3,40 @@ global switch_context
|
||||||
global get_context
|
global get_context
|
||||||
global restore_stack
|
global restore_stack
|
||||||
|
|
||||||
; switch_context(struct context *old, struct context *new)
|
; switch_context(struct context **old, *struct context new)
|
||||||
; ^RDI ^RSI
|
; ^RDI ^RSI
|
||||||
switch_context:
|
switch_context:
|
||||||
|
push rdi
|
||||||
pop r8 ; Fetch RIP from stack
|
push rsi
|
||||||
|
push rdx
|
||||||
; Save callee-saved registers to the old struct
|
push rcx
|
||||||
mov [rdi + 0x00], rbx
|
push rbx
|
||||||
mov [rdi + 0x08], rsp
|
push rbp
|
||||||
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 r8
|
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
|
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 "../mm/kmalloc.h"
|
||||||
#include "sched.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
|
#define QUANTUM_US 10000
|
||||||
|
|
||||||
int next_pid = 1;
|
int next_pid = 1;
|
||||||
|
|
||||||
void idle_task(){
|
void idle_task(){
|
||||||
kprintf("Hello world from idle task!\n");
|
for(;;){
|
||||||
|
kprintf("Idle!!1\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_task(){
|
void test_task(){
|
||||||
|
for(;;){
|
||||||
kprintf("Hello world from scheduled task!\n");
|
kprintf("Hello world from scheduled task!\n");
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void best_task(){
|
||||||
|
for(;;){
|
||||||
|
kprintf("Hello world I am best\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup a process structure */
|
/* Setup a process structure */
|
||||||
|
|
@ -36,12 +42,17 @@ proc *alloc_process(void){
|
||||||
|
|
||||||
p->state = READY;
|
p->state = READY;
|
||||||
|
|
||||||
p->kstack = kmalloc(INITIAL_STACK_SIZE);
|
p->kstack = kzalloc(8 * 4096);
|
||||||
|
|
||||||
p->pid = next_pid++;
|
p->pid = next_pid++;
|
||||||
|
|
||||||
p->context.rbp = (uint64_t)p->kstack;
|
uint64_t *sp = (uint64_t*)((uint64_t)p->kstack + 8 * 4096);
|
||||||
p->context.rsp = (uint64_t)p->context.rbp + INITIAL_STACK_SIZE;
|
|
||||||
|
// Allocate space for context
|
||||||
|
sp -= sizeof(context)/sizeof(uint64_t);
|
||||||
|
|
||||||
|
p->context = (context*)sp;
|
||||||
|
p->context->rbp = (uint64_t)p->kstack;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
@ -49,8 +60,10 @@ proc *alloc_process(void){
|
||||||
|
|
||||||
klog(__func__, "Couldnt find free process!!!!!!\n");
|
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();
|
proc *proc = alloc_process();
|
||||||
|
|
||||||
if (proc == NULL) {
|
if (proc == NULL) {
|
||||||
|
|
@ -58,29 +71,31 @@ proc *add_task(uint64_t *entry){
|
||||||
kkill();
|
kkill();
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->context.rip = (uint64_t)entry;
|
proc->context->rip = (uint64_t)entry;
|
||||||
|
|
||||||
|
kprintf("entry: 0x{xn}", entry);
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler_init(){
|
void scheduler_init(){
|
||||||
if(!get_cpu_struct_initialized()){
|
if(!get_cpu_struct_initialized()){
|
||||||
kprintf("sched: cpu struct not initialized!");
|
klog(__func__, "CPU struct not initialized!");
|
||||||
kkill();
|
kkill();
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_state *state = get_cpu_struct();
|
cpu_state *state = get_cpu_struct();
|
||||||
|
|
||||||
if(state->current_process != NULL){
|
if(state->current_process != NULL){
|
||||||
kprintf("sched: scheduler on CPU {d} already initialized!\n", state->lapic_id);
|
kprintf("scheduler on CPU {d} already initialized!\n", state->lapic_id);
|
||||||
kkill();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc *proc_list = state->process_list;
|
proc *proc_list = state->process_list;
|
||||||
|
|
||||||
memset(proc_list, 0, sizeof(proc) * 512);
|
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){
|
if(idle == NULL){
|
||||||
klog(__func__, "Failed to allocate idle task");
|
klog(__func__, "Failed to allocate idle task");
|
||||||
|
|
@ -89,27 +104,30 @@ void scheduler_init(){
|
||||||
|
|
||||||
state->current_process = idle;
|
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(;;){
|
||||||
for(int i = 0; i < PROC_MAX; i++){
|
for(; i < PROC_MAX; i++){
|
||||||
if(proc_list[i].state == READY){
|
if(proc_list[i].state == READY){
|
||||||
|
proc *prev = state->current_process;
|
||||||
context old_state = state->current_process->context;
|
prev->state = READY;
|
||||||
|
|
||||||
state->current_process = &proc_list[i];
|
state->current_process = &proc_list[i];
|
||||||
state->current_process->state = RUNNING;
|
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(){
|
void enter_scheduler(){
|
||||||
cpu_state *state = get_cpu_struct();
|
switch_context(&get_cpu_struct()->current_process->context, (get_cpu_struct()->scheduler_context));
|
||||||
proc *proc_list = state->process_list;
|
|
||||||
switch_context(&state->current_process->context, &state->scheduler_context);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -10,19 +10,19 @@ typedef enum proc_state {
|
||||||
}proc_state;
|
}proc_state;
|
||||||
|
|
||||||
typedef struct context {
|
typedef struct context {
|
||||||
uint64_t rbx, rsp, rbp, r12, r13, r14, r15;
|
uint64_t r15, r14, r13, r12, r11, r10, r9, r8, rbp, rbx, rcx, rdx, rsi, rdi, rip;
|
||||||
uint64_t rip;
|
} context;
|
||||||
} __attribute((packed))context;
|
|
||||||
|
|
||||||
typedef struct proc {
|
typedef struct proc {
|
||||||
uint64_t *mem;
|
uint64_t *mem;
|
||||||
uint64_t *kstack;
|
uint64_t *kstack;
|
||||||
proc_state state;
|
proc_state state;
|
||||||
uint16_t pid;
|
uint16_t pid;
|
||||||
context context;
|
context *context;
|
||||||
}proc;
|
}proc;
|
||||||
|
|
||||||
void scheduler_init();
|
void scheduler_init();
|
||||||
|
void enter_scheduler();
|
||||||
|
|
||||||
#define PROC_MAX 512 // Max number of processes
|
#define PROC_MAX 512 // Max number of processes
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue