removed pdclib, strange things were happening..., user shell kinda works now

This commit is contained in:
2026-07-06 22:13:57 -05:00
parent 7d76f0ec73
commit 6d7a23d747
308 changed files with 829 additions and 41231 deletions

View File

@@ -33,7 +33,7 @@ init_pic:
outb %al, $PIC2_DATA
# mask
mov $0xFE, %al
mov $0xF8, %al
outb %al, $PIC1_DATA
mov $0xFF, %al
outb %al, $PIC2_DATA

View File

@@ -2,13 +2,18 @@
#include <drivers/ps2/ps2.h>
static const char scancode_to_ascii[] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0,
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' '
};
extern void ps2_wait_input_empty(void);
extern void ps2_wait_output_full(void);
extern void ps2_write_command(uint8_t);
extern uint8_t ps2_read_data(void);
extern void ps2_write_data(uint8_t);
extern void ps2_flush_output_buffer(void);
extern void io_wait(void);
static uint8_t read_ccb() {
@@ -68,4 +73,19 @@ int init_ps2() {
write_ccb(ccb);
return 0;
}
}
char ps2_get_ascii(uint8_t scancode) {
if (scancode & 0x80) {
return 0;
}
if (scancode < sizeof(scancode_to_ascii)) {
char ascii = scancode_to_ascii[scancode];
if (ascii != 0) {
return ascii;
}
}
return 0;
}

View File

@@ -18,8 +18,11 @@
#ifndef __ASSEMBLER__
#include <stdint.h>
int init_ps2();
uint8_t ps2_read_data();
char ps2_get_ascii(uint8_t scancode);
#endif
#endif

View File

@@ -2,8 +2,7 @@
#include <lib/print.h>
#include "process.h"
#include "scheduler.h"
#include "kbd.h"
#include "syscall.h"
#include "common.h"
#include "gdt.h"
@@ -144,6 +143,11 @@ void common_interrupt_handler(intr_regs_t *args) {
kprintf("Current cr3: 0x%x\n", fetch_cr3());
if (args->cs == 0x1b) {
kprintf("User ESP: 0x%x\n", args->u_esp);
kprintf("ESP: 0x%x\t0x%x\t0x%x\t0x%x\n",
*(uint32_t*)args->u_esp,
*(uint32_t*)(args->u_esp + 4),
*(uint32_t*)(args->u_esp + 8),
*(uint32_t*)(args->u_esp + 12));
kprintf("User SS: 0x%x\n", args->u_ss);
}
kprintf("Caused by: %s, %s, running in %s mode\n",
@@ -158,8 +162,11 @@ void common_interrupt_handler(intr_regs_t *args) {
break;
}
case 33: {
kprintf("ps2 keyboard interrupt\n");
uint8_t data = ps2_read_data();
char ascii = ps2_get_ascii(data);
if (ascii != 0) {
kbd_push(ascii);
}
send_eoi_master();
break;
}

84
kernel/kbd.c Normal file
View File

@@ -0,0 +1,84 @@
#include "kbd.h"
#include "process.h"
#include "scheduler.h"
#include "common.h"
#include <lib/tasks.h>
#include <lib/print.h>
#include <stddef.h>
#define KBD_BUFFER_SIZE 256
static spinlock_t kbd_lock = {0};
static process_t* kbd_waiting_task = NULL;
static char kbd_buffer[KBD_BUFFER_SIZE];
static int kbd_head = 0;
static int kbd_tail = 0;
static void lock_kbd() {
disable_interrupts();
spin_lock(&kbd_lock);
}
static void unlock_kbd() {
spin_unlock(&kbd_lock);
enable_interrupts();
}
static void kbd_set_waiting(process_t* task) {
lock_kbd();
if (kbd_head == kbd_tail) {
kbd_waiting_task = task;
}
unlock_kbd();
}
static char kbd_pop() {
char c = 0;
lock_kbd();
if (kbd_head != kbd_tail) {
c = kbd_buffer[kbd_tail];
kbd_tail = (kbd_tail + 1) % KBD_BUFFER_SIZE;
}
unlock_kbd();
return c;
}
void kbd_push(char c) {
spin_lock(&kbd_lock);
// push to buffer first, very important
int next_head = (kbd_head + 1) % KBD_BUFFER_SIZE;
if (next_head != kbd_tail) {
kbd_buffer[kbd_head] = c;
kbd_head = next_head;
}
if (kbd_waiting_task != NULL) {
wake(kbd_waiting_task);
kbd_waiting_task = NULL;
}
spin_unlock(&kbd_lock);
}
int kbd_ready() {
int ready = 0;
lock_kbd();
ready = (kbd_head != kbd_tail);
unlock_kbd();
return ready;
}
void kbd_wait() {
process_t* task = current_task();
while (!kbd_ready()) {
task->state = STATE_BLOCKED;
kbd_set_waiting(task);
yield();
}
}
char kbd_read() {
return kbd_pop();
}

6
kernel/kbd.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
char kbd_read();
void kbd_push(char c);
int kbd_ready();
void kbd_wait();

View File

@@ -57,6 +57,7 @@ vfs_node_t* load_initrd() {
}
void load_root_program(const char* path) {
disable_interrupts();
uint32_t kernel_cr3 = fetch_cr3();
void* cr3 = create_task_pd();
load_pd(cr3);
@@ -129,6 +130,7 @@ void load_root_program(const char* path) {
*(--u_esp) = 0; // argc = 0
create_task(e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp);
enable_interrupts();
load_pd((void*)kernel_cr3);
flush_tlb();
@@ -169,7 +171,8 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
disable_interrupts();
init_scheduler();
load_root_program("/origin.elf");
kprintf("done loading origin program\n");
enable_interrupts();
kprintf("loading rocksh...\n");
load_root_program("/rocksh.elf");
}

View File

@@ -80,6 +80,11 @@ void kprintf(const char* fmt, ...) {
kputx(x);
break;
}
case 'c': {
int c = va_arg(args, int);
vga_putchar((char)c);
break;
}
case '%':
vga_putchar('%');
break;

View File

@@ -6,24 +6,31 @@
yield: # void yield()
cli
pushfl
pushl %cs
popl %ecx
pushfl // EFLAGS
pushl %cs // CS
pushl %ecx // EIP
movl 8(%esp), %eax
pushal
call send_eoi_master
xor %eax, %eax
mov %ds, %ax
pushl %eax
movl 4(%esp), %ebx # Get CS
movl %ebx, 8(%esp) # Move CS over Old EIP
movl 0(%esp), %ebx # Get Return EIP
movl %ebx, 4(%esp) # Move Return EIP over CS
addl $4, %esp # Adjust stack pointer up.
pushal
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
pushl %esp
call switch_context
movl %eax, %esp
popl %eax
mov %ax, %ds
mov %ax, %es
popal
sti
iret

View File

@@ -149,10 +149,16 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
}
process_t* current_task() {
lock_scheduler();
process_t* rtn = &process_table[current_process];
unlock_scheduler();
return rtn;
}
process_t* current_task_unsafe() {
return &process_table[current_process];
}
void sleep(uint32_t ms) {
if (ms == 0) return;
lock_scheduler();
@@ -169,3 +175,10 @@ void exit() {
unlock_scheduler();
}
void wake(process_t* task) {
lock_scheduler();
if (task->state == STATE_SLEEPING || task->state == STATE_BLOCKED) {
task->state = STATE_READY;
}
unlock_scheduler();
}

View File

@@ -12,5 +12,6 @@ process_t* current_task();
void sleep(uint32_t ms);
void yield();
void exit();
void wake(process_t* task);
#endif

View File

@@ -4,22 +4,18 @@
#include "memory/mm.h"
#include "process.h"
#include "scheduler.h"
#include "kbd.h"
#include <drivers/vga/vga.h>
#include <lib/print.h>
typedef struct registers {
uint32_t gs, fs, es, ds; // Pushed manually
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
uint32_t int_no, err_code; // Pushed manually
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU
} registers_t;
static int32_t sys_exit(int status) {
asm volatile("cli");
asm volatile("hlt");
process_t* task = current_task();
task->state = STATE_DEAD;
kprintf("Process %d exited with status %d\n", task->pid, status);
exit();
return 0;
}
@@ -35,13 +31,18 @@ static int32_t sys_write(int fd, const void* buf, size_t count) {
}
static int32_t sys_read(int fd, void* buf, size_t count) {
if (fd == 0) { // stdin
if (fd == 0) {
char* cbuf = (char*)buf;
size_t bytes_read = 0;
while (bytes_read < count) {
char c = 'r';
cbuf[bytes_read++] = c;
if (c == '\n') break;
kbd_wait();
if (kbd_ready()) {
char c = kbd_read();
cbuf[bytes_read++] = c;
if (c == '\n') break;
}
}
return bytes_read;
}
@@ -83,6 +84,12 @@ static int32_t sys_brk(uint32_t new_break) {
return current->heap_end;
}
typedef struct registers {
uint32_t gs, fs, es, ds; // Pushed manually
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
uint32_t int_no, err_code; // Pushed manually
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU
} registers_t;
int32_t syscall(registers_t* regs) {
switch(regs->eax) {
case 1: return sys_exit(regs->ebx);