heading to laptop

This commit is contained in:
2026-07-07 18:52:22 -05:00
parent 177a0b8fe9
commit e42ee8eb85
13 changed files with 68 additions and 96 deletions

View File

@@ -126,3 +126,8 @@ outsw:
fetch_cr3: fetch_cr3:
mov %cr3, %eax mov %cr3, %eax
ret ret
.global kpanic
kpanic:
cli
hlt

View File

@@ -7,6 +7,8 @@ void enable_interrupts();
void disable_interrupts(); void disable_interrupts();
uint32_t fetch_cr3(); uint32_t fetch_cr3();
void kpanic();
void liftoff(uint32_t entry_point, uint32_t user_stack) __attribute__((noreturn)); void liftoff(uint32_t entry_point, uint32_t user_stack) __attribute__((noreturn));
#endif #endif

View File

@@ -59,21 +59,16 @@ isr32:
pushal pushal
call send_eoi_master call send_eoi_master
xor %eax, %eax push %ds
mov %ds, %ax
pushl %eax
mov $0x10, %ax mov $0x10, %ax
mov %ax, %ds mov %ax, %ds
mov %ax, %es
pushl %esp pushl %esp
call switch_context call switch_context
movl %eax, %esp movl %eax, %esp
popl %eax pop %ds
mov %ax, %ds
mov %ax, %es
popal popal
sti sti

View File

@@ -6,6 +6,8 @@
#include "syscall.h" #include "syscall.h"
#include "common.h" #include "common.h"
#include "gdt.h" #include "gdt.h"
#include "scheduler.h"
#include "process.h"
#include <drivers/pic/pic.h> #include <drivers/pic/pic.h>
#include <drivers/ps2/ps2.h> #include <drivers/ps2/ps2.h>
@@ -114,8 +116,10 @@ void common_interrupt_handler(intr_regs_t *args) {
case 12: case 12:
case 13: case 13:
case 15: case 15:
case 16: case 16: {
process_t* task = current_task();
kprintf("\n--- CPU Exception ---\n"); kprintf("\n--- CPU Exception ---\n");
kprintf("Current Task PID: %d\n", task->pid);
kprintf("Error: [%d] %s\n", args->int_no, err_messages[args->int_no]); kprintf("Error: [%d] %s\n", args->int_no, err_messages[args->int_no]);
kprintf("Error Code: 0x%x\n", args->error_code); kprintf("Error Code: 0x%x\n", args->error_code);
kprintf("Instruction Pointer: 0x%x\n", args->eip); kprintf("Instruction Pointer: 0x%x\n", args->eip);
@@ -127,12 +131,16 @@ void common_interrupt_handler(intr_regs_t *args) {
kprintf("Current cr3: 0x%x\n", fetch_cr3()); kprintf("Current cr3: 0x%x\n", fetch_cr3());
kprintf("tss.esp0: 0x%x\n", tss.esp0); kprintf("tss.esp0: 0x%x\n", tss.esp0);
kprintf("instruction: 0x%x\n", *(uint32_t*)args->eip); kprintf("instruction: 0x%x\n", *(uint32_t*)args->eip);
asm volatile("hlt"); kpanic();
break; break;
}
case 14:{ case 14:{
disable_interrupts();
uint32_t faulting_address; uint32_t faulting_address;
process_t* task = current_task();
asm volatile("mov %%cr2, %0" : "=r"(faulting_address)); asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
kprintf("\n--- PAGE FAULT ---\n"); kprintf("\n--- PAGE FAULT ---\n");
kprintf("Current Task PID: %d\n", task->pid);
kprintf("Faulted Virtual Address: 0x%x\n", faulting_address); kprintf("Faulted Virtual Address: 0x%x\n", faulting_address);
kprintf("Error Code: 0x%x\n", args->error_code); kprintf("Error Code: 0x%x\n", args->error_code);
kprintf("Instruction Pointer: 0x%x\n", args->eip); kprintf("Instruction Pointer: 0x%x\n", args->eip);
@@ -154,7 +162,7 @@ void common_interrupt_handler(intr_regs_t *args) {
(args->error_code & 0x01) ? "Protection Violation" : "Page Not Present", (args->error_code & 0x01) ? "Protection Violation" : "Page Not Present",
(args->error_code & 0x02) ? "Write" : "Read", (args->error_code & 0x02) ? "Write" : "Read",
(args->error_code & 0x04) ? "User" : "Supervisor"); (args->error_code & 0x04) ? "User" : "Supervisor");
asm volatile("hlt"); kpanic();
break; break;
} }
case 32: { case 32: {

View File

@@ -57,9 +57,10 @@ vfs_node_t* load_initrd() {
} }
void load_root_program(const char* path) { void load_root_program(const char* path) {
disable_interrupts(); lock_scheduler();
uint32_t kernel_cr3 = fetch_cr3(); uint32_t kernel_cr3 = fetch_cr3();
void* cr3 = create_task_pd(); void* cr3 = create_task_pd();
load_pd(cr3); load_pd(cr3);
flush_tlb(); flush_tlb();
@@ -132,7 +133,8 @@ void load_root_program(const char* path) {
process_t* process = kalloc(sizeof(process_t)); process_t* process = kalloc(sizeof(process_t));
init_task(process, e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp); init_task(process, e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp);
add_task(process); add_task(process);
enable_interrupts();
unlock_scheduler();
load_pd((void*)kernel_cr3); load_pd((void*)kernel_cr3);
flush_tlb(); flush_tlb();
@@ -177,4 +179,6 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
kprintf("loading test program\n"); kprintf("loading test program\n");
load_root_program("/test.elf"); load_root_program("/test.elf");
kprintf("kernel going to sleep...\n");
} }

View File

@@ -2,7 +2,7 @@
#include "multiboot.h" #include "multiboot.h"
#include <stddef.h> #include <stddef.h>
#include <lib/string.h> #include <lib/memory.h>
extern uint8_t __kernel_start; extern uint8_t __kernel_start;
extern uint8_t __kernel_end; extern uint8_t __kernel_end;

View File

@@ -17,34 +17,20 @@ static process_t* idle_task = NULL;
static int total_processes = 0; static int total_processes = 0;
static void lock_scheduler() { void lock_scheduler() {
disable_interrupts(); disable_interrupts();
} }
static void unlock_scheduler() { void unlock_scheduler() {
enable_interrupts(); enable_interrupts();
} }
uint32_t switch_context(uint32_t current_esp) { uint32_t switch_context(uint32_t current_esp) {
current_process->esp = current_esp; current_process->esp = current_esp;
for (int i = 0; i < total_processes; i++) { process_t* next_process = current_process->sched_next;
if (process_table[i].state == STATE_SLEEPING) {
if (process_table[i].sleep > 0) {
process_table[i].sleep--;
}
if (process_table[i].sleep == 0) {
process_table[i].state = STATE_READY;
}
}
}
process_t* next_process = current_process;
int found_ready = 0; int found_ready = 0;
while (next_process != NULL) {
while (1) {
next_process = (process_t*)next_process->sched_next;
if (next_process != idle_task && next_process->state == STATE_READY) { if (next_process != idle_task && next_process->state == STATE_READY) {
found_ready = 1; found_ready = 1;
break; break;
@@ -53,10 +39,12 @@ uint32_t switch_context(uint32_t current_esp) {
if (next_process == current_process) { if (next_process == current_process) {
break; break;
} }
next_process = (process_t*)next_process->sched_next;
} }
if (!found_ready) { if (!found_ready) {
if (current_process->state == STATE_READY) { if (current_process && current_process->state == STATE_READY) {
next_process = current_process; next_process = current_process;
} else { } else {
next_process = idle_task; next_process = idle_task;
@@ -68,6 +56,7 @@ uint32_t switch_context(uint32_t current_esp) {
uint32_t current_cr3 = fetch_cr3(); uint32_t current_cr3 = fetch_cr3();
if (current_cr3 != current_process->cr3) { if (current_cr3 != current_process->cr3) {
load_pd((void*)current_process->cr3); load_pd((void*)current_process->cr3);
flush_tlb();
} }
if (current_process->flags & PROCESS_FLAG_USER) { if (current_process->flags & PROCESS_FLAG_USER) {
@@ -145,25 +134,19 @@ void init_task (
} }
int get_next_pid() { int get_next_pid() {
lock_scheduler();
int pid = total_processes; int pid = total_processes;
total_processes++; total_processes++;
unlock_scheduler();
return pid; return pid;
} }
void add_task(process_t* task) { void add_task(process_t* task) {
lock_scheduler();
if (!task) { if (!task) {
unlock_scheduler();
return; return;
} }
if (process_table->sched_next == NULL) { if (process_table->sched_next == NULL) {
process_table->sched_next = task; process_table->sched_next = task;
task->sched_next = process_table; task->sched_next = process_table;
unlock_scheduler();
return; return;
} }
@@ -174,37 +157,27 @@ void add_task(process_t* task) {
curr->sched_next = task; curr->sched_next = task;
task->sched_next = process_table; task->sched_next = process_table;
unlock_scheduler();
} }
process_t* current_task() { process_t* current_task() {
lock_scheduler();
process_t* rtn = current_process; process_t* rtn = current_process;
unlock_scheduler();
return rtn; return rtn;
} }
void sleep(uint32_t ms) { void sleep(uint32_t ms) {
if (ms == 0) return; if (ms == 0) return;
lock_scheduler();
current_process->sleep = ms; current_process->sleep = ms;
current_process->state = STATE_SLEEPING; current_process->state = STATE_SLEEPING;
yield(); yield();
unlock_scheduler();
} }
void exit() { void exit() {
lock_scheduler();
current_process->state = STATE_DEAD; current_process->state = STATE_DEAD;
yield(); // yield forever yield(); // yield forever
unlock_scheduler();
} }
void wake(process_t* task) { void wake(process_t* task) {
lock_scheduler();
if (task->state == STATE_SLEEPING || task->state == STATE_BLOCKED) { if (task->state == STATE_SLEEPING || task->state == STATE_BLOCKED) {
task->state = STATE_READY; task->state = STATE_READY;
} }
unlock_scheduler();
} }

View File

@@ -4,6 +4,9 @@
#include "process.h" #include "process.h"
#include <stdint.h> #include <stdint.h>
void lock_scheduler();
void unlock_scheduler();
void init_scheduler(); void init_scheduler();
void init_task(process_t* process, uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp); void init_task(process_t* process, uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp);

View File

@@ -4,33 +4,16 @@
syscall_handler: syscall_handler:
cli cli
push $0 pushal
push $0x80
pusha
push %ds push %ds
push %es
push %fs
push %gs
mov $0x10, %ax mov $0x10, %ax
mov %ax, %ds mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
push %esp push %esp
call syscall call syscall
add $4, %esp add $4, %esp
mov 28(%esp), %eax
pop %gs
pop %fs
pop %es
pop %ds pop %ds
popal
popa
add $8, %esp
iret iret

View File

@@ -2,7 +2,6 @@
#include <stddef.h> #include <stddef.h>
#include <drivers/pty/pty.h> #include <drivers/pty/pty.h>
#include "common.h"
#include "lib/memory.h" #include "lib/memory.h"
#include "lib/ringbuf.h" #include "lib/ringbuf.h"
#include "memory/mm.h" #include "memory/mm.h"
@@ -16,11 +15,10 @@
#include <lib/string.h> #include <lib/string.h>
typedef struct registers { typedef struct registers {
uint32_t gs, fs, es, ds; // Pushed manually uint32_t ds; // push %ds
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushal
uint32_t int_no, err_code; // Pushed manually uint32_t eip, cs, eflags, useresp, ss; // pushed by cpu
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU } __attribute__((packed)) registers_t;
} registers_t;
static int32_t sys_exit(int status) { static int32_t sys_exit(int status) {
process_t* task = current_task(); process_t* task = current_task();
@@ -126,7 +124,7 @@ static int32_t sys_pty(int* slave_fd) {
static int32_t sys_fork(registers_t* parent_regs) { static int32_t sys_fork(registers_t* parent_regs) {
process_t* parent = current_task(); process_t* parent = current_task();
process_t* child = kalloc(sizeof(process_t)); process_t* child = kalloc(sizeof(process_t));
if (!child) { if (!child) {
return -1; return -1;
@@ -142,36 +140,37 @@ static int32_t sys_fork(registers_t* parent_regs) {
child->fd_table[i] = parent->fd_table[i]; child->fd_table[i] = parent->fd_table[i];
} }
disable_interrupts();
uint32_t kstack_size = 4096; uint32_t kstack_size = 4096;
void* kstack_alloc = kalloc(kstack_size); void* kstack_alloc = kalloc(kstack_size);
child->kstack_top = (uint32_t)kstack_alloc + kstack_size; child->kstack_top = (uint32_t)kstack_alloc + kstack_size;
child->cr3 = (uint32_t)clone_task_pd();
registers_t* child_regs = (registers_t*)(child->kstack_top - sizeof(registers_t)); registers_t* child_regs = (registers_t*)(child->kstack_top - sizeof(registers_t));
memcpy(child_regs, parent_regs, sizeof(registers_t)); memcpy(parent_regs, child_regs, sizeof(registers_t));
child_regs->eax = 0; child_regs->eax = 0;
child->esp = (uint32_t)child_regs; child->esp = (uint32_t)child_regs;
enable_interrupts(); kprintf("child registers for PID %d\n", child->pid);
kprintf("\tEIP: 0x%x\n", child_regs->eip);
// uint32_t cr3 = (uint32_t)clone_task_pd();
child->cr3 = parent->cr3;
add_task(child); add_task(child);
return child->pid; return child->pid;
} }
int32_t syscall(registers_t* regs) { void syscall(registers_t* regs) {
int32_t ret;
switch(regs->eax) { switch(regs->eax) {
case 1: return sys_exit(regs->ebx); case 1: ret = sys_exit(regs->ebx); break;
case 3: return sys_read(regs->ebx, (void*)regs->ecx, regs->edx); case 3: ret = sys_read(regs->ebx, (void*)regs->ecx, regs->edx); break;
case 4: return sys_write(regs->ebx, (const void*)regs->ecx, regs->edx); case 4: ret = sys_write(regs->ebx, (const void*)regs->ecx, regs->edx); break;
case 5: return sys_open((const char*)regs->ebx, regs->ecx); case 5: ret = sys_open((const char*)regs->ebx, regs->ecx); break;
case 6: return sys_close(regs->ebx); case 6: ret = sys_close(regs->ebx); break;
case 12: return sys_brk(regs->ebx); case 12: ret = sys_brk(regs->ebx); break;
case 20: return sys_pty((int*)regs->ebx); case 20: ret = sys_pty((int*)regs->ebx); break;
case 21: return sys_fork(regs); case 21: ret = sys_fork(regs); break;
default: default: ret = -1;
return -1;
} }
regs->eax = ret;
} }

Binary file not shown.

View File

@@ -4,9 +4,10 @@ int main(int argc, char *argv[]) {
(void)argc; (void)argc;
(void)argv; (void)argv;
if (!fork()) { int fk = 0;
exit(1); if ((fk = fork()) > 0) {
return fk;
} }
return 0; return 0;
} }

View File

@@ -11,7 +11,6 @@ static inline int syscall1(int num, uint32_t arg1) {
return ret; return ret;
} }
/* A generic wrapper for a system call with 3 arguments */
static inline int syscall3(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) { static inline int syscall3(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) {
int ret; int ret;
asm volatile ( asm volatile (