Update keyboard driver, add start of file handlers, stdio.
This commit is contained in:
parent
fc2c73225b
commit
55a5bea35a
4
Makefile
4
Makefile
@ -2,8 +2,7 @@ CFLAGS = -g -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exce
|
||||
CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I.
|
||||
LDFLAGS =
|
||||
|
||||
DISK_IMG_FILES = build/kernel/kernel.bin build/program/program.bin build/hello/hello.bin \
|
||||
build/world/world.bin hello.txt alpha.txt
|
||||
DISK_IMG_FILES = build/kernel/kernel.bin build/world/world.bin hello.txt alpha.txt
|
||||
|
||||
KERNEL_CPP_SRCS = $(wildcard src/kernel/*.cpp) $(wildcard src/kernel/*/*.cpp)
|
||||
KERNEL_ASM_SRCS = $(wildcard src/kernel/*.asm)
|
||||
@ -54,6 +53,7 @@ prepare:
|
||||
mkdir -p build/boot_stage2
|
||||
mkdir -p build/kernel
|
||||
mkdir -p build/kernel/datatypes
|
||||
mkdir -p build/kernel/stdio
|
||||
mkdir -p build/program
|
||||
mkdir -p build/hello
|
||||
mkdir -p build/world
|
||||
|
@ -146,9 +146,9 @@ void main() {
|
||||
// But first, we should load the kernel somewhere
|
||||
|
||||
uint8_t* kernel_location = 0x542000; // Just load it at 0x524000 for now
|
||||
mark_unavailble(kernel_location, 32768, bitmap); // Just treat the kernel as not growing beyond 32k for now.
|
||||
mark_unavailble(kernel_location, 0x10000, bitmap); // Just treat the kernel as not growing beyond 32k for now.
|
||||
|
||||
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 8); // Map 8 pages from 0x522000 to 0xc0000000;
|
||||
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 8 pages from 0x522000 to 0xc0000000;
|
||||
map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000
|
||||
map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000
|
||||
map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000
|
||||
@ -159,7 +159,7 @@ void main() {
|
||||
|
||||
memset(vm_bitmap, 0x20000, 0xff);
|
||||
|
||||
mark_unavailble(0xc0000000, 0x8000, vm_bitmap);
|
||||
mark_unavailble(0xc0000000, 0x10000, vm_bitmap);
|
||||
mark_unavailble(0xc0100000, 0x1000, vm_bitmap);
|
||||
mark_unavailble(0xc0101000, 0x400000, vm_bitmap);
|
||||
mark_unavailble(0xc0501000, 0x1000, vm_bitmap);
|
||||
@ -175,9 +175,9 @@ void main() {
|
||||
|
||||
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
|
||||
// Map the stack
|
||||
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6);
|
||||
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 6);
|
||||
mark_unavailble(0x8a000, 0x6000, bitmap);
|
||||
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 16);
|
||||
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 16);
|
||||
mark_unavailble(0x8a000, 0x10000, bitmap);
|
||||
|
||||
load_file("KERNEL BIN", kernel_location);
|
||||
|
||||
|
@ -1,19 +1,11 @@
|
||||
#include "common.h"
|
||||
|
||||
void print(char* string) {
|
||||
asm volatile ("mov $0, %%eax; mov %0, %%esi; int $0x7f" : : "m" (string) : "eax", "esi");
|
||||
}
|
||||
|
||||
char getch() {
|
||||
asm volatile ("mov $1, %%eax; int $0x7f" : : :);
|
||||
}
|
||||
|
||||
uint8_t getchPS2() {
|
||||
asm volatile ("mov $2, %%eax; int $0x7f" : : :);
|
||||
}
|
||||
|
||||
void readfile(char* filename, uint8_t* buffer) {
|
||||
asm volatile ("mov $3, %%eax; mov %0, %%esi; mov %1, %%edi; int $0x7f" : : "m" (filename), "m" (buffer) : "eax", "esi", "edi");
|
||||
char* c = string;
|
||||
int i=0;
|
||||
while (*(c++))
|
||||
i++;
|
||||
write(i, 0, (uint8_t*)string);
|
||||
}
|
||||
|
||||
void* localalloc(uint32_t size) {
|
||||
@ -24,14 +16,22 @@ void localdelete(void* ptr) {
|
||||
asm volatile ("mov $5, %%eax; mov %0, %%esi; int $0x7f" : : "m" (ptr) : "esi");
|
||||
}
|
||||
|
||||
uint32_t filesize(char* filename) {
|
||||
asm volatile ("mov $6, %%eax; mov %0, %%esi; int $0x7f" : : "m" (filename) : "esi");
|
||||
}
|
||||
|
||||
uint32_t getPID() {
|
||||
asm volatile ("mov $8, %%eax; int $0x7f" : : :);
|
||||
}
|
||||
|
||||
int read(uint32_t count, void* filehanlder, uint8_t* buffer) {
|
||||
asm volatile ("mov $10, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi");
|
||||
}
|
||||
|
||||
int write(uint32_t count, void* filehanlder, uint8_t* buffer) {
|
||||
asm volatile ("mov $11, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi");
|
||||
}
|
||||
|
||||
void bindToKeyboard() {
|
||||
asm volatile ("mov $12, %%eax; int $0x7f" : : :);
|
||||
}
|
||||
|
||||
int int_to_decimal(unsigned int number, char* string_buffer) {
|
||||
for (int i=0; i<11; i++)
|
||||
string_buffer[i] = 0;
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include "../kernel/types.h"
|
||||
|
||||
void print(char* string);
|
||||
char getch();
|
||||
uint8_t getchPS2();
|
||||
void readfile(char* filename, uint8_t* buffer);
|
||||
void* localalloc(uint32_t size);
|
||||
void localdelete(void* ptr);
|
||||
@ -13,6 +11,10 @@ uint32_t filesize(char* filename);
|
||||
|
||||
uint32_t getPID();
|
||||
|
||||
int read(uint32_t count, void* filehandler, uint8_t* buffer);
|
||||
int write(uint32_t count, void* filehandler, uint8_t* buffer);
|
||||
void bindToKeyboard();
|
||||
|
||||
int int_to_decimal(unsigned int number, char* string_buffer);
|
||||
int int_to_hex(unsigned int number, char* string_buffer);
|
||||
|
||||
|
@ -5,7 +5,6 @@ int main() {
|
||||
uint32_t PID = getPID();
|
||||
char intbuffer[32];
|
||||
uint32_t index = int_to_decimal(PID, intbuffer);
|
||||
uint32_t x = *(uint32_t*)0xdeadbeef;
|
||||
while (1) {
|
||||
counter++;
|
||||
if (counter == 312500) {
|
||||
|
@ -22,6 +22,16 @@ namespace xnoe {
|
||||
xnoe::linkedlistelem<T>* start;
|
||||
xnoe::linkedlistelem<T>* end;
|
||||
|
||||
bool has(T t) {
|
||||
xnoe::linkedlistelem<T>* current = this->start;
|
||||
while (start) {
|
||||
if (start->elem == t)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void append(T t) {
|
||||
xnoe::linkedlistelem<T>* llelem = new xnoe::linkedlistelem<T>(t);
|
||||
append(llelem);
|
||||
|
@ -1,7 +1,7 @@
|
||||
[BITS 32]
|
||||
|
||||
_start:
|
||||
mov esp, 0xc1005ffc
|
||||
mov esp, 0xc100a000
|
||||
jmp main
|
||||
|
||||
extern main
|
@ -136,63 +136,112 @@ void context_switch(frame_struct* frame) {
|
||||
// Set the current proc to valid
|
||||
Global::currentProcValid = true;
|
||||
|
||||
uint32_t* espVal;
|
||||
asm ("mov %%esp, %0":"=a"(espVal):);
|
||||
if (*espVal == 0) {
|
||||
if (Global::currentProc->firstRun) {
|
||||
Global::currentProc->firstRun = false;
|
||||
asm("add $4, %esp");
|
||||
asm("ret");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t current_scancode;
|
||||
extern char decoded;
|
||||
|
||||
void syscall(frame_struct* 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)
|
||||
// 0: X
|
||||
// 1: X
|
||||
// 2: X
|
||||
// 3: X
|
||||
// 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)
|
||||
// 6: X
|
||||
// 7: X
|
||||
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
||||
// 9: getFileHandler :: char* path esi -> void* eax // Returns a file handlers for a specific file
|
||||
// 10: read :: uint32_t count ebx -> void* filehandler esi -> uint8_t* outputbuffer edi -> int read // Reads from a file handler in to a buffer, returns successful read
|
||||
// 11: write :: uint32_t count ebx -> void* filehandler esi -> uint8_t* inputbuffer edi -> int written // Reads from a buffer in to a file, returns successful written
|
||||
// 12: bindToKeyboard :: void -> void // Binds the current process's stdout to the keyboard.
|
||||
|
||||
// File handlers:
|
||||
// 0: Stdout
|
||||
// 1: Stdin
|
||||
// 2..7: Reserved
|
||||
// _: General use
|
||||
|
||||
uint32_t rval = frame->eax;
|
||||
|
||||
uint32_t esi = frame->esi;
|
||||
uint32_t edi = frame->edi;
|
||||
|
||||
Process* currentProc = Global::currentProc;
|
||||
|
||||
switch (frame->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);
|
||||
rval = currentProc->allocate(esi);
|
||||
break;
|
||||
case 5:
|
||||
Global::currentProc->deallocate(esi);
|
||||
currentProc->deallocate(esi);
|
||||
break;
|
||||
case 6:
|
||||
rval = file_size(esi);
|
||||
break;
|
||||
case 7: {
|
||||
Global::kernel->createProcess(esi);
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
rval = currentProc->PID;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
break;
|
||||
|
||||
case 10: {
|
||||
if (esi == 1) {
|
||||
ReadWriter* stdin = currentProc->stdin;
|
||||
if (!stdin)
|
||||
break;
|
||||
|
||||
rval = stdin->read(frame->ebx, edi);
|
||||
} else {
|
||||
xnoe::Maybe<ReadWriter*> fh = Global::kernel->FH->get(esi);
|
||||
if (!fh.is_ok())
|
||||
break;
|
||||
|
||||
ReadWriter* rw = fh.get();
|
||||
rval = rw->read(frame->ebx, edi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
rval = Global::currentProc->PID;
|
||||
|
||||
case 11: {
|
||||
if (esi == 0) {
|
||||
ReadWriter* stdout = currentProc->stdout;
|
||||
if (!stdout)
|
||||
break;
|
||||
|
||||
rval = stdout->write(frame->ebx, edi);
|
||||
} else {
|
||||
xnoe::Maybe<ReadWriter*> fh = Global::kernel->FH->get(esi);
|
||||
if (!fh.is_ok())
|
||||
break;
|
||||
|
||||
ReadWriter* rw = fh.get();
|
||||
rval = rw->write(frame->ebx, edi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 12:
|
||||
if (currentProc->stdin)
|
||||
break;
|
||||
|
||||
currentProc->stdin = new CircularRWBuffer(currentProc->PID, 0);
|
||||
Global::kernel->KBListeners.append(currentProc);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "global.h"
|
||||
#include "kernel.h"
|
||||
#include "gdt.h"
|
||||
#include "stdio/circularrwbuffer.h"
|
||||
|
||||
struct __attribute__((packed)) frame_struct {
|
||||
uint32_t edi;
|
||||
|
@ -29,6 +29,12 @@ Process* Kernel::createProcess(char* filename) {
|
||||
return p;
|
||||
}
|
||||
|
||||
Process* Kernel::createProcess(char* filename, ReadWriter* stdout) {
|
||||
Process* p = this->createProcess(filename);
|
||||
p->stdout = stdout;
|
||||
return p;
|
||||
}
|
||||
|
||||
void Kernel::destroyProcess(Process* p) {
|
||||
this->processes.remove(p);
|
||||
this->pid_map->remove(p->PID, p);
|
||||
|
@ -14,14 +14,17 @@ public:
|
||||
Terminal* terminal;
|
||||
|
||||
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
||||
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
||||
|
||||
xnoe::linkedlist<Process*> processes;
|
||||
xnoe::linkedlist<Process*> KBListeners;
|
||||
|
||||
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack);
|
||||
|
||||
void init_kernel();
|
||||
|
||||
Process* createProcess(char* filename);
|
||||
Process* createProcess(char* filename, ReadWriter* stdout);
|
||||
void destroyProcess(Process* p);
|
||||
//void loadPrimaryStack();
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "keyboard.h"
|
||||
|
||||
char key_to_char[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||
0, 0, '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, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
@ -11,8 +11,8 @@ char key_to_char[128] = {
|
||||
};
|
||||
|
||||
char key_to_char_caps[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
|
||||
0, 0, '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, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
@ -21,8 +21,8 @@ char key_to_char_caps[128] = {
|
||||
};
|
||||
|
||||
char key_to_char_shift[128] = {
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
||||
0, 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, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
@ -30,14 +30,12 @@ char key_to_char_shift[128] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
uint8_t current_scancode = 0;
|
||||
char decoded = 0;
|
||||
|
||||
bool caps_on = false;
|
||||
bool shift_on = false;
|
||||
|
||||
void keyboard_interrupt(frame_struct* frame) {
|
||||
current_scancode = inb(0x60);
|
||||
uint8_t decoded = 0;
|
||||
uint8_t current_scancode = inb(0x60);
|
||||
outb(0x20, 0x21);
|
||||
if ((current_scancode&0x7f) == 0x2a)
|
||||
shift_on = !(current_scancode&0x80);
|
||||
@ -51,6 +49,15 @@ void keyboard_interrupt(frame_struct* frame) {
|
||||
decoded = key_to_char_caps[current_scancode&0x7f];
|
||||
else
|
||||
decoded = key_to_char[current_scancode&0x7f];
|
||||
|
||||
if (current_scancode < 0x80) {
|
||||
xnoe::linkedlist<Process*> KBListeners = Global::kernel->KBListeners;
|
||||
xnoe::linkedlistelem<Process*>* current = KBListeners.start;
|
||||
while (current) {
|
||||
current->elem->stdin->write(1, &decoded);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_keyboard() {
|
||||
|
@ -46,8 +46,8 @@ int main() {
|
||||
|
||||
Global::currentProc = &kernel;
|
||||
|
||||
Process* p1 = kernel.createProcess("WORLD BIN");
|
||||
kernel.createProcess("HELLO BIN");
|
||||
Process* p1 = kernel.createProcess("WORLD BIN", term);
|
||||
//kernel.createProcess("HELLO BIN");
|
||||
|
||||
init_keyboard();
|
||||
|
||||
|
@ -35,6 +35,11 @@ Process::Process(uint32_t PID)
|
||||
|
||||
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename)
|
||||
: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) {
|
||||
this->stdout = 0;
|
||||
this->stdin = 0;
|
||||
|
||||
this->firstRun = true;
|
||||
|
||||
this->PID = PID;
|
||||
this->page_remaining = 0;
|
||||
this->last_page_pointer = 0;
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "global.h"
|
||||
#include "atapio.h"
|
||||
|
||||
#include "stdio/readwriter.h"
|
||||
|
||||
struct AllocTracker {
|
||||
void* page_base;
|
||||
uint32_t page_size;
|
||||
@ -37,6 +39,11 @@ public:
|
||||
void* kernelStackPtr;
|
||||
void* kernelStackPtrDefault;
|
||||
|
||||
ReadWriter* stdout;
|
||||
ReadWriter* stdin;
|
||||
|
||||
bool firstRun;
|
||||
|
||||
Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||
Process(uint32_t PID);
|
||||
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename);
|
||||
|
40
src/kernel/stdio/circularrwbuffer.cpp
Normal file
40
src/kernel/stdio/circularrwbuffer.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "circularrwbuffer.h"
|
||||
|
||||
CircularRWBuffer::CircularRWBuffer(uint32_t reader, uint32_t writer)
|
||||
: ReadWriter(0) {
|
||||
this->giveReadPerm(reader);
|
||||
this->giveWritePerm(writer);
|
||||
|
||||
this->bufferSize = 3072;
|
||||
this->buffer = new uint8_t[this->bufferSize];
|
||||
this->readPtr = 0;
|
||||
this->writePtr = 0;
|
||||
}
|
||||
|
||||
int CircularRWBuffer::write(uint32_t count, uint8_t* buffer) {
|
||||
int i=0;
|
||||
while (i < count) {
|
||||
this->buffer[this->writePtr] = buffer[i];
|
||||
|
||||
this->writePtr++;
|
||||
if (this->writePtr == this->bufferSize)
|
||||
this->writePtr = 0;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int CircularRWBuffer::read(uint32_t count, uint8_t* buffer) {
|
||||
int i=0;
|
||||
while (i < count) {
|
||||
if (this->readPtr == this->writePtr)
|
||||
return 0;
|
||||
buffer[i] = this->buffer[this->readPtr];
|
||||
|
||||
this->readPtr++;
|
||||
if (this->readPtr == this->bufferSize)
|
||||
this->readPtr = 0;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
19
src/kernel/stdio/circularrwbuffer.h
Normal file
19
src/kernel/stdio/circularrwbuffer.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef CIRCULAR_RW_BUFFER_H
|
||||
#define CIRCULAR_RW_BUFFER_H
|
||||
|
||||
#include "readwriter.h"
|
||||
|
||||
class CircularRWBuffer : public ReadWriter {
|
||||
private:
|
||||
uint8_t* buffer;
|
||||
uint32_t readPtr;
|
||||
uint32_t writePtr;
|
||||
uint32_t bufferSize;
|
||||
public:
|
||||
CircularRWBuffer(uint32_t reader, uint32_t writer);
|
||||
|
||||
int read(uint32_t count, uint8_t* buffer) override;
|
||||
int write(uint32_t count, uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
#endif
|
36
src/kernel/stdio/readwriter.cpp
Normal file
36
src/kernel/stdio/readwriter.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "readwriter.h"
|
||||
|
||||
ReadWriter::ReadWriter(uint32_t owner) {
|
||||
this->owner = owner;
|
||||
}
|
||||
|
||||
void ReadWriter::giveReadPerm(uint32_t PID) {
|
||||
this->allowedRead.append(PID);
|
||||
}
|
||||
|
||||
void ReadWriter::giveWritePerm(uint32_t PID) {
|
||||
this->allowedWrite.append(PID);
|
||||
}
|
||||
|
||||
int ReadWriter::read(uint32_t count, uint8_t* buffer){}
|
||||
int ReadWriter::write(uint32_t count, uint8_t* buffer){}
|
||||
|
||||
bool ReadWriter::canRead(uint32_t PID) {
|
||||
if (this->owner == PID)
|
||||
return true;
|
||||
|
||||
if (this->allowedRead.has(PID))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadWriter::canWrite(uint32_t PID) {
|
||||
if (this->owner == PID)
|
||||
return true;
|
||||
|
||||
if (this->allowedWrite.has(PID))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
25
src/kernel/stdio/readwriter.h
Normal file
25
src/kernel/stdio/readwriter.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef READWRITER_H
|
||||
#define READWRITER_H
|
||||
|
||||
#include "../datatypes/linkedlist.h"
|
||||
#include "../types.h"
|
||||
|
||||
class ReadWriter {
|
||||
private:
|
||||
uint32_t owner;
|
||||
xnoe::linkedlist<uint32_t> allowedRead;
|
||||
xnoe::linkedlist<uint32_t> allowedWrite;
|
||||
|
||||
public:
|
||||
ReadWriter(uint32_t owner);
|
||||
void giveReadPerm(uint32_t PID);
|
||||
void giveWritePerm(uint32_t PID);
|
||||
|
||||
virtual int read(uint32_t count, uint8_t* buffer);
|
||||
virtual int write(uint32_t count, uint8_t* buffer);
|
||||
uint32_t getOwner();
|
||||
bool canRead(uint32_t PID);
|
||||
bool canWrite(uint32_t PID);
|
||||
};
|
||||
|
||||
#endif
|
@ -31,7 +31,8 @@ void Terminal::update(){}
|
||||
void Terminal::update_cur(){}
|
||||
void Terminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {}
|
||||
|
||||
Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) {
|
||||
Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
||||
: ReadWriter(0) {
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->pages = pages;
|
||||
@ -124,6 +125,18 @@ void Terminal::printf(const char* string, ...) {
|
||||
va_end(ptr);
|
||||
}
|
||||
|
||||
int Terminal::write(uint32_t count, uint8_t* buffer) {
|
||||
char* buf = new char[count+1];
|
||||
for (int i=0;i<count;i++) {
|
||||
buf[i] = buffer[i];
|
||||
}
|
||||
buf[count] = 0;
|
||||
printf(buf);
|
||||
delete buf;
|
||||
}
|
||||
|
||||
int Terminal::read(uint32_t count, uint8_t* buffer) {}
|
||||
|
||||
void Terminal::clear_screen() {
|
||||
for (int i=0; i < width * height * pages; i++) {
|
||||
buffer[i] = 0;
|
||||
|
@ -8,7 +8,9 @@
|
||||
#include "strings.h"
|
||||
#include "io.h"
|
||||
|
||||
class Terminal {
|
||||
#include "stdio/readwriter.h"
|
||||
|
||||
class Terminal: public ReadWriter {
|
||||
private:
|
||||
virtual void update();
|
||||
virtual void update_cur();
|
||||
@ -36,6 +38,9 @@ public:
|
||||
|
||||
void printf(const char* string, ...);
|
||||
|
||||
int write(uint32_t count, uint8_t* buffer) override;
|
||||
int read(uint32_t count, uint8_t* buffer) override;
|
||||
|
||||
void clear_screen();
|
||||
void set_curpos(int x, int y);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
_start:
|
||||
call main
|
||||
int 0x80
|
||||
_loop:
|
||||
jmp _loop
|
||||
|
||||
extern main
|
@ -1,94 +1,14 @@
|
||||
#include "../common/common.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
char key_to_char[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0,
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
|
||||
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
char key_to_char_caps[128] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\',
|
||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
char key_to_char_shift[128] = {
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|',
|
||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
|
||||
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
bool caps_on = false;
|
||||
bool shift_on = false;
|
||||
|
||||
void readline(int max, char* buffer) {
|
||||
int index = 0;
|
||||
uint8_t current_scancode = getchPS2();
|
||||
|
||||
uint8_t char_print[2];
|
||||
char_print[0] = 0;
|
||||
char_print[1] = 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 (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 (scancode == 0x0e) {
|
||||
if (index > 0) {
|
||||
buffer[--index] = 0;
|
||||
print("\b");
|
||||
}
|
||||
} else if (decoded && scancode < 0x80) {
|
||||
buffer[index++] = decoded;
|
||||
char_print[0] = decoded;
|
||||
print(char_print);
|
||||
}
|
||||
|
||||
while (scancode == current_scancode)
|
||||
current_scancode = getchPS2();
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
bindToKeyboard();
|
||||
|
||||
print("Hello from Ring 3!\n");
|
||||
|
||||
char buffer[128];
|
||||
while (1) {
|
||||
for (int i=0; i<128; i++)
|
||||
buffer[i] = 0;
|
||||
print(">>> ");
|
||||
readline(128, buffer);
|
||||
print("\nYou said: ");
|
||||
print(buffer);
|
||||
print("\n");
|
||||
char c;
|
||||
if (read(1, 1, &c))
|
||||
write(1, 0, &c);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user