From 0bb88e4da8be75bf3867ee5fedbda2385d56cda4 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Sat, 27 Nov 2021 02:32:28 +0000 Subject: [PATCH] Add system calls, update keybaord, add Terminal* field to kernel. Update process.cpp to load a program called program.bin from disk rather than hardcoding data --- src/kernel/idt.cpp | 64 +++++++++++++++++++++++++++++++++++++++++ src/kernel/kernel.h | 2 ++ src/kernel/keyboard.cpp | 58 +++++++++++-------------------------- src/kernel/kmain.cpp | 8 ++---- src/kernel/process.cpp | 17 ++++------- src/kernel/process.h | 1 + 6 files changed, 90 insertions(+), 60 deletions(-) diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 9d0641c..8923f27 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -105,6 +105,69 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) { } } +extern uint8_t current_scancode; +extern char decoded; + +__attribute__((interrupt)) void syscall(interrupt_frame* frame) { + // Syscall ABI: + // 0: print: Print null terminated string (in esi: char*) + // 1: getch: Get current keyboard character ASCII (out eax: char) + // 2: getchPS2: Get current keyboard character PS/2 code (out eax: char) + // 3: readfile: Load file to location (in esi: char* filename; in edi: uint8_t* buffer) + // 4: localalloc: LocalAlloc: Allocate under current process (in esi: size; out eax void* ptr) + // 5: localdelete: LocalDelete: Deallocate under current process (in esi: pointer) + // 6: filesize: Get file size (in esi: char* filename; out eax size bytes) + // 7: fork: create process from filename (in esi: char* filename) + + uint32_t* ebp; + asm("mov %%ebp, %0" : "=a" (ebp) :); + uint32_t eax = *(ebp-4); + uint32_t rval = eax; + + uint32_t syscall_number; + uint32_t esi; + uint32_t edi; + asm("mov %%esi, %0" : "=a" (esi) :); + asm("mov %%edi, %0" : "=a" (edi) :); + switch (eax) { + case 0: + Global::kernel->terminal->printf("%s", (char*)esi); + break; + case 1: + rval = decoded; + break; + case 2: + rval = current_scancode; + break; + case 3: + load_file(esi, edi); + break; + case 4: + rval = Global::currentProc->allocate(esi); + break; + case 5: + Global::currentProc->deallocate(esi); + break; + case 6: + rval = file_size(esi); + break; + case 7: { + uint32_t size = file_size(esi); + uint8_t* filebuffer = new uint8_t[size]; + load_file(esi, filebuffer); + Global::kernel->createProcess(); + break; + } + default: + break; + } + + asm volatile ("mov %0, %%eax" : : "m" (rval)); + asm ("mov %ebp, %esp"); + asm ("pop %ebp"); + asm ("iret"); +} + void init_idt() { idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt}; asm volatile("lidt %0" : : "m" (desc)); @@ -115,6 +178,7 @@ void init_idt() { set_entry(0xD, 0x08, &gpf, 0x8E); set_entry(0xE, 0x08, &page_fault, 0x8E); set_entry(0x80, 0x08, &context_switch, 0x8E); + set_entry(0x7f, 0x08, &syscall, 0x8E); outb(0x20, 0x11); outb(0xA0, 0x11); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index c020359..7804a42 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -4,10 +4,12 @@ #include "process.h" #include "datatypes/hashtable.h" #include "global.h" +#include "terminal.h" class Kernel : public Process { public: uint32_t currentPID; + Terminal* terminal; xnoe::hashtable* pid_map; // Map of PIDs -> Process*s diff --git a/src/kernel/keyboard.cpp b/src/kernel/keyboard.cpp index fa66bf1..6c1fc07 100644 --- a/src/kernel/keyboard.cpp +++ b/src/kernel/keyboard.cpp @@ -31,10 +31,26 @@ char key_to_char_shift[128] = { }; uint8_t current_scancode = 0; +char decoded = 0; + +bool caps_on = false; +bool shift_on = false; __attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) { current_scancode = inb(0x60); outb(0x20, 0x21); + if ((current_scancode&0x7f) == 0x2a) + shift_on = !(current_scancode&0x80); + + if (current_scancode == 0x3a) + caps_on ^= 1; + + if (shift_on) + decoded = key_to_char_shift[current_scancode&0x7f]; + else if (caps_on) + decoded = key_to_char_caps[current_scancode&0x7f]; + else + decoded = key_to_char[current_scancode&0x7f]; } void init_keyboard() { @@ -50,46 +66,4 @@ void init_keyboard() { outb(0x64, 0x60); outb(0x60, keyboard_status); outb(0x60, 0xF4); -} - -bool caps_on = false; -bool shift_on = false; - -void readline(int max, char* buffer) { - int index = 0; - - - uint8_t scancode = 0; - while (scancode != 0x1c && index < max) { - scancode = current_scancode; - - char decoded = 0; - - if ((scancode&0x7f) == 0x2a) - shift_on = !(scancode&0x80); - - if (scancode == 0x3a) - caps_on ^= 1; - - if (scancode == 0x0e && index > 0) { - set_curpos_raw(get_curpos()-1); - non_moving_put(' '); - buffer[--index] = 0; - } - - if (shift_on) - decoded = key_to_char_shift[scancode&0x7f]; - else if (caps_on) - decoded = key_to_char_caps[scancode&0x7f]; - else - decoded = key_to_char[scancode&0x7f]; - - if (decoded && scancode < 0x80) { - buffer[index++] = decoded; - printf("%c", decoded); - } - - while (scancode == current_scancode); - } - printf("\n"); } \ No newline at end of file diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 444ca35..0e1f6fb 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -29,14 +29,11 @@ int main() { Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000); kernel.init_kernel(); - - Terminal* current_term; + init_atapio(); TextModeTerminal* term = new TextModeTerminal(0xc0501000); - current_term = term; - TextModeTerminal* term2 = new TextModeTerminal(0xc0501000); - term2->printf("Balls"); + kernel.terminal = term; init_idt(); @@ -62,7 +59,6 @@ int main() { init_keyboard(); enable_idt(); - init_atapio(); uint8_t* filebuffer = new uint8_t[0x3000]; diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index 9ea3e91..218bd56 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -44,16 +44,17 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase) uint32_t pCR3; asm ("mov %%cr3, %0" : "=a" (pCR3) :); this->PD->select(); - + + uint8_t* program_data = this->allocate(file_size("PROGRAM BIN") + 12) + 12; + // We also need to initialise ESP and the stack uint32_t* stack32 = ((uint32_t)this->stack + 0x8000); - printf("stack32: %x\n", stack32); stack32--; *stack32 = 0x0; // EFLAGS stack32--; *stack32 = 8; // CS 0x08 stack32--; - *stack32 = 0x14; // Execution will begin from 0x14 + *stack32 = (uint32_t)program_data; stack32--; *stack32 = ((uint32_t)this->stack + 0x8000); // EBP @@ -78,16 +79,8 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase) *stack32 = 0; // EDI this->esp = stack32; - printf("this->esp: %x\n", stack32); - /*((uint8_t*)this->stack)[0] = 0xe9; - ((uint8_t*)this->stack)[1] = 0xfb; - ((uint8_t*)this->stack)[2] = 0xff; - ((uint8_t*)this->stack)[3] = 0xff; - ((uint8_t*)this->stack)[4] = 0xff;*/ - - ((uint8_t*)this->stack)[0] = 0xcd; - ((uint8_t*)this->stack)[1] = 0x80; + load_file("PROGRAM BIN", program_data); asm ("mov %0, %%cr3" : : "r" (pCR3)); } diff --git a/src/kernel/process.h b/src/kernel/process.h index c2b72a5..c297e9e 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -8,6 +8,7 @@ #include "datatypes/maybe.h" #include "screenstuff.h" #include "global.h" +#include "atapio.h" struct AllocTracker { void* page_base;