trying to make the keyboard driver work, right now I am suffering.

This commit is contained in:
Justus Wolff
2026-04-06 00:48:38 +02:00
parent fd968a06ce
commit 9d94299fb1
19 changed files with 590 additions and 51 deletions

View File

@@ -6,6 +6,8 @@ KERNEL_PHYS_BASE = 0x00100000;
SECTIONS { SECTIONS {
. = KERNEL_VIRT_BASE; . = KERNEL_VIRT_BASE;
kernel_start = .;
.text : AT(KERNEL_PHYS_BASE) { .text : AT(KERNEL_PHYS_BASE) {
*(.text) *(.text)
} }
@@ -22,4 +24,6 @@ SECTIONS {
*(COMMON) *(COMMON)
*(.bss) *(.bss)
} }
kernel_end = .;
} }

View File

@@ -9,11 +9,14 @@ build: prepare copygrub
gcc -c src/kernel/tty.c -o build/tty.o -ffreestanding -O2 -Wall -Wextra -m32 # tty gcc -c src/kernel/tty.c -o build/tty.o -ffreestanding -O2 -Wall -Wextra -m32 # tty
gcc -c src/kernel/interrupts.c -o build/interrupts.o -ffreestanding -O2 -Wall -Wextra -m32 # interrupts, C side gcc -c src/kernel/interrupts.c -o build/interrupts.o -ffreestanding -O2 -Wall -Wextra -m32 # interrupts, C side
gcc -c src/kernel/scheduler.c -o build/scheduler.o -ffreestanding -O2 -Wall -Wextra -m32 # scheduler gcc -c src/kernel/scheduler.c -o build/scheduler.o -ffreestanding -O2 -Wall -Wextra -m32 # scheduler
gcc -c src/kernel/memMap.c -o build/memMap.o -ffreestanding -O2 -Wall -Wextra -m32 # memory map
gcc -c src/memManager/src.c -o build/memManager.o -ffreestanding -O2 -Wall -Wextra -m32 # memory manager
gcc -c src/kernel/keyboard.c -o build/keyboard.o -ffreestanding -O2 -Wall -Wextra -m32 # keyboard driver
gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver
tar -czf build/initrd build/initrddir/* # build initrd tar -czf build/initrd build/initrddir/* # build initrd
gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/scheduler.o build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/keyboard.o build/memManager.o build/memMap.o build/scheduler.o build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link
cp build/linked build/grub/boot/kernel # copy kernel over to grub template cp build/linked build/grub/boot/kernel # copy kernel over to grub template
cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template

View File

@@ -20,7 +20,7 @@ extern size_t VGA_rsx;
extern size_t VGA_rsy; extern size_t VGA_rsy;
void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val); void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val, VGA_pixel color);
void VGA_renderchar(virtualConsole* con); void VGA_renderchar(virtualConsole* con);
void _VGA_renchar(uint8_t x, uint8_t y, char val, uint8_t fcolor[3], uint8_t bcolor[3]); void _VGA_renchar(uint8_t x, uint8_t y, char val, uint8_t fcolor[3], uint8_t bcolor[3]);
void VGA_switch(uint8_t *regs); void VGA_switch(uint8_t *regs);

View File

@@ -1,21 +1,14 @@
#include "stddef.h" #include "stddef.h"
#include "stdlib.h" #include "stdlib.h"
#include "scheduler.h"
#define KEYBOARD_cmd_setled 0xED #define KBD_DATA 0x60
#define KEYBOARD_cmd_echo 0xEE #define KBD_STATUS 0x64
#define KEYBOARD_cmd_setscanset 0xF0 #define KBD_ACK 0xFA
#define KEYBOARD_cmd_enable 0xF4 #define KBD_RESEND 0xFE
#define KEYBOARD_cmd_disable 0xF5 #define BUF_SIZE 256
#define KEYBOARD_cmd_reset 0xFF
#define KEYBOARD_resp_ACK 0xFA
#define KEYBOARD_resp_resend 0xFE
#define KEYBOARD_resp_err 0x00
#define KEYBOARD_resp_selftestpass 0xAA
#define KEYBOARD_resp_echo 0xEE
#define KEYBOARD_resp_testfail1 0xFC
#define KEYBOARD_resp_testfail2 0xFD
#define KEYBOARD_resp_err2 0xFF
#define KEYBOARD_cqsize 128
extern uint8_t KEYBOARD_cmdqueue[KEYBOARD_cqsize]; void keyboard_init();
extern size_t KEYBOARD_cmdqueuesize; void keyboard_irq_handler();
void keyboard_process();
void keyboard_loop();

16
src/headers/memMap.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include "stddef.h"
#include "stdlib.h"
#include "multiboot2.h"
#define PAGE_SIZE 4096
#define MAX_PAGES 1048576 // 4 GB
extern uint8_t page_bitmap[MAX_PAGES / 8];
extern size_t page_bitmap_memsize;
extern uint8_t page_usebitmap[MAX_PAGES / 8];
void process_mmap(struct multiboot_tag_mmap* mmap_tag);
void* allocPages(size_t amount, uint8_t* success);
void freePages(void* addr, size_t amount);
void reservepages(void* addr, size_t length);

View File

@@ -6,4 +6,6 @@ typedef PAG_PT_entry_t PAG_PT_t[1024];
typedef PAG_PT_t PAG_PD_t[1024]; typedef PAG_PT_t PAG_PD_t[1024];
extern PAG_PD_t PAG_mainPD; extern PAG_PD_t PAG_mainPD;
extern PAG_PT_t PAG_identityPT;
extern PAG_PT_t PAG_kernelPT;

View File

@@ -1,3 +1,4 @@
#pragma once
#include "stddef.h" #include "stddef.h"
#include "stdlib.h" #include "stdlib.h"

View File

@@ -1,11 +1,20 @@
#define uint8_t unsigned char #define uint8_t unsigned char
#define uint16_t unsigned short #define uint16_t unsigned short
#define uint32_t unsigned int #define uint32_t unsigned long
//#define uint64_t unsigned long #define uint64_t unsigned long long
#define int8_t signed char #define int8_t signed char
#define int16_t signed short #define int16_t signed short
#define int32_t signed int #define int32_t signed long
#//define int64_t signed long #define int64_t signed long long
#define size_t uint32_t #define size_t uint64_t
extern uint32_t kernel_start;
extern uint32_t kernel_end;
#define HC_kernel_start ((uint32_t)&kernel_start-0xC0000000)
#define HC_kernel_end ((uint32_t)&kernel_end-0xC0000000)
#define OK "&gOK\n"
#define YES "&gYES\n"
#define NO "&rNO\n"

View File

@@ -1,12 +1,17 @@
#pragma once #pragma once
#include "stddef.h" #include "stddef.h"
void uiprint64(uint64_t x, void* func);
uint32_t strlen32(char* str); uint32_t strlen32(char* str);
uint64_t strlen64(char* str);
void strrev32(char* str); void strrev32(char* str);
void strrev64(char* str);
uint8_t uitoa32(uint32_t x, char* str); uint8_t uitoa32(uint32_t x, char* str);
uint8_t uitoa64(uint64_t x, char* str);
void strcon(char* x, char* y); void strcon(char* x, char* y);
void memcopy(void* dest, void* src, size_t size); void memcopy(void* dest, void* src, size_t size);
void memset(void* dest, size_t size, uint8_t value); void memset(void* dest, size_t size, uint8_t value);
void memmove(void* dest, void* src, size_t size);
__attribute__((noreturn)) __attribute__((noreturn))
void kpanic(char* msg); void kpanic(char* msg);
static inline void outb(uint16_t port, uint8_t val) { static inline void outb(uint16_t port, uint8_t val) {

View File

@@ -4,13 +4,22 @@
#define CON_sizex 40 #define CON_sizex 40
#define CON_sizey 25 #define CON_sizey 25
static size_t colorSize = 5;
static char colorcodes[5] = {'w', 'r', 'g', 'b', 'N'};
typedef struct {
char x;
uint8_t color[3];
} colorChar;
typedef struct { typedef struct {
void* FU_kupdbuf; void* FU_kupdbuf;
char kstdout[8192]; char kstdout[CON_sizex*CON_sizey];
uint16_t kstdout_count; uint16_t kstdout_count;
uint16_t kstdout_offset;
uint8_t FU_forecolor[3]; uint8_t FU_forecolor[3];
uint8_t FU_backcolor[3]; uint8_t FU_backcolor[3];
char charbuf[CON_sizex][CON_sizey]; colorChar charbuf[CON_sizex][CON_sizey];
uint8_t enableRendering; uint8_t enableRendering;
uint16_t keyBuf[1024]; uint16_t keyBuf[1024];
@@ -27,4 +36,8 @@ void con_kputstr(virtualConsole* con, char* x);
void con_init(virtualConsole* con); void con_init(virtualConsole* con);
void kputchar(char x); void kputchar(char x);
void kputstr(char* x); void kputstr(char* x);
void con_render(); void con_render();
void con_putkey(virtualConsole* con, uint16_t key);
uint16_t con_popkey(virtualConsole* con);
uint8_t con_iskeyavail(virtualConsole* con);
uint16_t con_gettopkey(virtualConsole* con);

View File

@@ -5,6 +5,9 @@
#include "../headers/tty.h" #include "../headers/tty.h"
#include "../headers/interrupts.h" #include "../headers/interrupts.h"
#include "../headers/scheduler.h" #include "../headers/scheduler.h"
#include "../headers/memMap.h"
#include "../headers/keyboard.h"
#include "../memManager/header.h"
struct multiboot_info { struct multiboot_info {
uint32_t total_size; uint32_t total_size;
@@ -24,18 +27,25 @@ uint32_t findtag(uint32_t type, struct multiboot_info* info) {
return 0; // failsafe return 0; // failsafe
} }
void printok() {
kputstr(OK);
schedule_task_fl(1, &printok);
}
void kernel_main(struct multiboot_info* header, uint32_t magic) { void kernel_main(struct multiboot_info* header, uint32_t magic) {
// init all consoles // init all consoles
for (uint8_t i=0;i<consolesAmount;i++) { for (uint8_t i=0;i<consolesAmount;i++) {
con_init(&consoles[i]); con_init(&consoles[i]);
} }
kputstr("Hello JPOS, World!\n"); kputstr("-----&gHello JPOS, World!&N-----\n");
kputstr("Entering Graphics mode: "); kputstr("Entering Graphics mode: ");
VGA_switch(VGA_values); VGA_switch(VGA_values);
*(uint8_t*)0xA0000 = 1; *(uint8_t*)0xA0000 = 1;
kputstr("OK\n"); kputstr(OK);
kputstr("Reserving pages for framebuffer...");
reservepages(VGA_fbuf, VGA_rsx*VGA_rsy);
kputstr(OK);
VGA_clear((VGA_pixel){0xFF,0xFF,0xFF}); VGA_clear((VGA_pixel){0xFF,0xFF,0xFF});
@@ -48,7 +58,7 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
while (1) {} while (1) {}
} }
} }
kputstr("OK\n"); kputstr(OK);
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) { if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
kputstr("Invalid magic from bootloader.\n"); kputstr("Invalid magic from bootloader.\n");
@@ -62,30 +72,64 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E); idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
IRQ_entries[i].inuse = 0; IRQ_entries[i].inuse = 0;
} }
kputstr("OK\n"); kputstr(OK);
kputstr("Setting up interrupts: "); kputstr("Setting up interrupts: ");
idt_init(); idt_init();
kputstr("OK\n"); kputstr(OK);
kputstr("Initializing PICs: "); kputstr("Initializing PICs: ");
PIC_remap(0x20,0x28); PIC_remap(0x20,0x28);
kputstr("OK\n"); kputstr(OK);
kputstr("Enabling Interrupts: "); kputstr("Enabling Interrupts: ");
asm volatile("sti"); asm volatile("sti");
kputstr("OK\n"); kputstr(OK);
kputstr("Initializing Timer: "); kputstr("Initializing Timer: ");
uint32_t divisor = 1193180 / SCHED_freq; uint32_t divisor = 1193180 / SCHED_freq;
uint8_t low = (uint8_t)(divisor & 0xFF); uint8_t low = (uint8_t)(divisor & 0xFF);
uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF); uint8_t high = (uint8_t)((divisor >> 8) & 0xFF);
outb(0x43, 0x36); outb(0x43, 0x36);
outb(0x40, low); outb(0x40, low);
outb(0x40, high); outb(0x40, high);
kputstr("OK\n"); kputstr(OK);
IRQ_registerhandler(0x00, &tick); IRQ_registerhandler(0x00, &tick);
while (1) {} kputstr("Kernel size: ");
uiprint64(HC_kernel_end-HC_kernel_start, kputstr);
kputstr("\n");
kputstr("Kernel start: ");
uiprint64(HC_kernel_start, kputstr);
kputstr("\n");
kputstr("Kernel end: ");
uiprint64(HC_kernel_end, kputstr);
kputstr("\n");
struct multiboot_tag_mmap* mmap = (struct multiboot_tag_mmap*)&header->tags[findtag(MULTIBOOT_TAG_TYPE_MMAP, header)];
process_mmap(mmap);
kputstr("Available pages: ");
uiprint64(page_bitmap_memsize, kputstr);
kputstr("\n");
kputstr("Available memory: ");
uiprint64(page_bitmap_memsize*PAGE_SIZE, kputstr);
kputstr(" Bytes\n");
kputstr("Initializing memory manager...");
MEM_pagalloc = &allocPages;
MEM_pagfree = &freePages;
kputstr(OK);
kputstr("Initializing Keyboard...");
IRQ_registerhandler(0x01, &keyboard_irq_handler);
keyboard_init();
keyboard_loop();
kputstr(OK);
while (1) {
if (con_iskeyavail(&consoles[currentConsole])) {
kputchar(con_popkey(&consoles[currentConsole]));
}
}
} }

View File

@@ -206,7 +206,7 @@ void _VGA_renchar(uint8_t x, uint8_t y, char val, uint8_t fcolor[3], uint8_t bco
void VGA_renderchar(virtualConsole* con) { void VGA_renderchar(virtualConsole* con) {
for (size_t x=0;x<CON_sizex;x++) { for (size_t x=0;x<CON_sizex;x++) {
for (size_t y=0;y<CON_sizey;y++) { for (size_t y=0;y<CON_sizey;y++) {
_VGA_renchar(x, y, con->charbuf[x][y], con->FU_forecolor, con->FU_backcolor); _VGA_renchar(x, y, con->charbuf[x][y].x, con->charbuf[x][y].color, con->FU_backcolor);
} }
} }
} }
@@ -295,22 +295,32 @@ void VGA_setpal(uint8_t palette[256][3]) {
VGA_setpix(i,0,(VGA_pixel){0x00,0xFF,0x00}); VGA_setpix(i,0,(VGA_pixel){0x00,0xFF,0x00});
} }
} }
void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val) { void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val, VGA_pixel color) {
con->charbuf[x][y] = val; con->charbuf[x][y] = (colorChar){val, {color.r, color.g, color.b}};
}
uint8_t beginswith(char* x, char* y) {
for (size_t i=0;i<strlen64(y);i++) {
if (x[i] != y[i]) {return 0;}
}
return 1;
} }
void VGA_kstrrend(virtualConsole* con) { void VGA_kstrrend(virtualConsole* con) {
VGA_clear((VGA_pixel){0x00,0x00,0x00}); VGA_clear(*(VGA_pixel*)con->FU_backcolor);
size_t count = con->kstdout_count; size_t count = con->kstdout_count;
char* buf = con->kstdout; char* buf = con->kstdout;
while (count > (CON_sizex*CON_sizey)) {
count -= (CON_sizex*CON_sizey);
buf += (CON_sizex*CON_sizey);
}
uint16_t x = 0; uint16_t x = 0;
uint16_t y = 0; uint16_t y = 0;
VGA_pixel ccolor = *(VGA_pixel*)con->FU_forecolor;
for (uint16_t i=0;i<count;i++) { for (uint16_t i=0;i<count;i++) {
while (y >= CON_sizey) {
for (size_t cy=1;cy<CON_sizey;cy++) {
for (size_t cx=0;cx<CON_sizex;cx++) {
con->charbuf[cx][cy-1] = con->charbuf[cx][cy];
}
}
y --;
}
if (x >= CON_sizex) { if (x >= CON_sizex) {
x = 0; x = 0;
y ++; y ++;
@@ -318,12 +328,35 @@ void VGA_kstrrend(virtualConsole* con) {
char val = buf[i]; char val = buf[i];
if (val == '\n') { if (val == '\n') {
ccolor = (VGA_pixel){con->FU_forecolor[0], con->FU_forecolor[1], con->FU_forecolor[2]};
x = 0; x = 0;
y ++; y ++;
continue; continue;
} }
if (val == '&') {
VGA_pixel colors[5] = {
{0xFF, 0xFF, 0xFF},
{0xFF, 0x00, 0x00},
{0x00, 0xFF, 0x00},
{0x00, 0x00, 0xFF},
*(VGA_pixel*)con->FU_forecolor,
};
uint8_t found = 0;
for (size_t f=0;f<colorSize;f++) {
if (buf[i+1] == colorcodes[f]) {
ccolor = colors[f];
found = 1;
break;
}
}
if (found) {
i ++;
continue;
}
}
VGA_setchar(con,x,y,val); VGA_setchar(con,x,y,val,ccolor);
x++; x++;
} }

112
src/kernel/keyboard.c Normal file
View File

@@ -0,0 +1,112 @@
#include "../headers/keyboard.h"
#include "../headers/tty.h"
static uint8_t buffer[BUF_SIZE];
static uint32_t head = 0;
static uint32_t tail = 0;
static void buffer_push(uint8_t val) {
buffer[head++ % BUF_SIZE] = val;
}
static int buffer_pop(uint8_t *val) {
if (tail == head) return 0;
*val = buffer[tail++ % BUF_SIZE];
return 1;
}
static void wait_input_empty() {
while (inb(KBD_STATUS) & 2) {} // IBF full
}
static void wait_output_full() {
while (!(inb(KBD_STATUS) & 1)) {} // OBF empty
}
static uint8_t keyboard_send(uint8_t cmd) {
wait_input_empty();
outb(KBD_DATA, cmd);
wait_output_full();
uint8_t resp = inb(KBD_DATA);
if (resp == KBD_ACK) return 0;
if (resp == KBD_RESEND) return keyboard_send(cmd);
return 1;
}
void keyboard_init() {
while (inb(KBD_STATUS) & 1) {
inb(KBD_DATA);
}
wait_input_empty();
outb(KBD_STATUS, 0xAE);
wait_input_empty();
outb(KBD_STATUS, 0x20);
wait_output_full();
uint8_t config = inb(KBD_DATA);
config |= 1;
wait_input_empty();
outb(KBD_STATUS, 0x60);
wait_input_empty();
outb(KBD_DATA, config);
keyboard_send(0xF0);
keyboard_send(0x01);
}
void keyboard_irq_handler() {
while (inb(KBD_STATUS) & 1) {
uint8_t sc = inb(KBD_DATA);
buffer_push(sc);
}
}
void keyboard_process() {
uint8_t sc;
while (buffer_pop(&sc)) {
if (sc & 0x80) continue;
// for gods sake, I gotta replace this with dynamic values, my hands sound like a cement mixer from typing all of this
char c = '?';
switch (sc) {
case 0x1E: c = 'a'; break;
case 0x30: c = 'b'; break;
case 0x2E: c = 'c'; break;
case 0x20: c = 'd'; break;
case 0x12: c = 'e'; break;
case 0x21: c = 'f'; break;
case 0x22: c = 'g'; break;
case 0x23: c = 'h'; break;
case 0x17: c = 'i'; break;
case 0x24: c = 'j'; break;
case 0x25: c = 'k'; break;
case 0x26: c = 'l'; break;
case 0x32: c = 'm'; break;
case 0x31: c = 'n'; break;
case 0x18: c = 'o'; break;
case 0x19: c = 'p'; break;
case 0x10: c = 'q'; break;
case 0x13: c = 'r'; break;
case 0x1F: c = 's'; break;
case 0x14: c = 't'; break;
case 0x16: c = 'u'; break;
case 0x2F: c = 'v'; break;
case 0x11: c = 'w'; break;
case 0x2D: c = 'x'; break;
case 0x15: c = 'y'; break;
case 0x2C: c = 'z'; break;
case 0x39: c = ' '; break;
default: c = '?'; break;
}
con_putkey(&consoles[currentConsole], c);
}
}
void keyboard_loop() {
keyboard_process();
schedule_task_fl(0.01, &keyboard_loop);
}

109
src/kernel/memMap.c Normal file
View File

@@ -0,0 +1,109 @@
#include "../headers/memMap.h"
uint8_t page_bitmap[MAX_PAGES / 8] = {};
size_t page_bitmap_memsize = 0;
uint8_t page_usebitmap[MAX_PAGES / 8] = {};
// helper functions
uint64_t align_up(uint64_t x) {
return (x + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
}
uint64_t align_down(uint64_t x) {
return x & ~(PAGE_SIZE - 1);
}
void set_bit(uint32_t page) {
page_bitmap[page / 8] |= (1 << (page % 8));
}
void clear_bit(uint32_t page) {
page_bitmap[page / 8] &= ~(1 << (page % 8));
}
void set_page_inuse(uint32_t page) {
page_usebitmap[page / 8] |= (1 << (page % 8));
}
void clear_page_inuse(uint32_t page) {
page_usebitmap[page / 8] &= ~(1 << (page % 8));
}
void mark_page_free(uint64_t addr) {
uint32_t page = addr / PAGE_SIZE;
clear_bit(page); // 0 = free
}
void mark_page_reserved(uint64_t addr) {
uint32_t page = addr / PAGE_SIZE;
set_bit(page); // 1 = used
}
uint8_t is_pageind_free(uint64_t page) {
return !(page_bitmap[page / 8] & (1 << (page % 8)));
}
uint8_t is_page_free(uint64_t addr) {
return is_pageind_free(addr / PAGE_SIZE);
}
uint8_t is_pageind_inuse(uint64_t page) {
return !(page_usebitmap[page / 8] & (1 << (page % 8)));
}
// juicy main functions
void reservepages(void* addr, size_t length) {
for (uint32_t i=(uint32_t)addr;i<(addr+length);i += PAGE_SIZE) {
mark_page_reserved(i);
}
}
void process_mmap(struct multiboot_tag_mmap* mmap_tag) {
for (uint8_t* entry_ptr = (uint8_t*)(mmap_tag + 1);entry_ptr < (uint8_t*)mmap_tag + mmap_tag->size;entry_ptr += mmap_tag->entry_size) {
struct multiboot_mmap_entry* entry = (struct multiboot_mmap_entry*)entry_ptr;
uint64_t start = entry->addr;
uint64_t end = entry->addr + entry->len;
// align to page boundaries
uint64_t p_start = align_up(start);
uint64_t p_end = align_down(end);
for (uint64_t addr = p_start; addr < p_end; addr += PAGE_SIZE) {
if (entry->type == 1) { // usable, needs to be remapped
mark_page_free(addr);
} else { // no touchy touchy
mark_page_reserved(addr);
}
page_bitmap_memsize ++;
}
}
for (uint32_t addr = HC_kernel_start;addr < HC_kernel_end;addr += PAGE_SIZE) { // areas with the kernel should be kept free
mark_page_reserved(addr);
}
}
void* allocPages(size_t amount, uint8_t* success) {
if (amount == 0) {return 0;}
size_t a = 0;
size_t ind = 0;
for (size_t i=0;i<page_bitmap_memsize;i++) {
if (a == amount) {
for (i=ind;i<ind+a;i++) {
set_page_inuse(i);
}
*success = 1;
return (void*)(ind*PAGE_SIZE);
}
if (is_pageind_free(i) && is_pageind_inuse(i)) {
if (a == 0) {ind = i;}
a ++;
} else {
a = 0;
}
}
if (a == amount) {
for (size_t i=ind;i<ind+a;i++) {
set_page_inuse(i);
}
*success = 1;
return (void*)(ind*PAGE_SIZE);
}
*success = 0;
return (void*)0;
}
void freePages(void* addr, size_t amount) {
size_t page = (size_t)addr/PAGE_SIZE;
for (size_t i=0;i<amount;i++) {
clear_page_inuse(page+i);
}
}

View File

@@ -1,7 +1,9 @@
#include "../headers/scheduler.h" #include "../headers/scheduler.h"
#include "../headers/interrupts.h"
task_t tasks[SCHED_tasksize]; task_t tasks[SCHED_tasksize];
uint8_t tasksbusy = 0; uint8_t tasksbusy = 0;
uint8_t isTicking = 0;
void acquiretasks() { void acquiretasks() {
while (tasksbusy) {} while (tasksbusy) {}
@@ -13,19 +15,23 @@ void freetasks() {
void tick() { void tick() {
if (tasksbusy) {return;} if (tasksbusy) {return;}
acquiretasks(); acquiretasks();
isTicking = 1;
for (size_t i=0;i<SCHED_tasksize;i++) { for (size_t i=0;i<SCHED_tasksize;i++) {
if (tasks[i].inUse) { if (tasks[i].inUse) {
tasks[i].ticks --; tasks[i].ticks --;
if (tasks[i].ticks == 0) { if (tasks[i].ticks == 0) {
tasks[i].inUse = 0; tasks[i].inUse = 0;
if (tasks[i].type == 0) { // callback if (tasks[i].type == 0) { // callback
freetasks();
((void (*)())tasks[i].callback)(); ((void (*)())tasks[i].callback)();
acquiretasks();
} else if (tasks[i].type == 1) { // reset } else if (tasks[i].type == 1) { // reset
*(uint8_t*)tasks[i].callback = 0; *(uint8_t*)tasks[i].callback = 0;
} }
} }
} }
} }
isTicking = 0;
freetasks(); freetasks();
} }
size_t schedule_task(size_t tick, void* callback) { size_t schedule_task(size_t tick, void* callback) {
@@ -45,6 +51,12 @@ size_t schedule_task(size_t tick, void* callback) {
return 0; return 0;
} }
uint8_t schedule_sleep(size_t tick) { uint8_t schedule_sleep(size_t tick) {
if (isTicking) {
//kpanic("Attempt to schedule a sleep inside a tick.");
// we simply re-enable interrupts.
asm("sti");
PIC_sendEOI(0);
}
volatile uint8_t wait = 1; volatile uint8_t wait = 1;
acquiretasks(); acquiretasks();
for (size_t i=0;i<SCHED_tasksize+1;i++) { for (size_t i=0;i<SCHED_tasksize+1;i++) {

View File

@@ -1,6 +1,11 @@
#include "../headers/stdlib.h" #include "../headers/stdlib.h"
#include "../headers/graphics.h" #include "../headers/graphics.h"
uint64_t strlen64(char* str) {
uint64_t i = 0;
while (*str++ != 0) {i++;}
return i;
}
uint32_t strlen32(char* str) { uint32_t strlen32(char* str) {
uint32_t i = 0; uint32_t i = 0;
while (*str++ != 0) {i++;} while (*str++ != 0) {i++;}
@@ -14,7 +19,21 @@ void strrev32(char* str) {
str[j] = c; str[j] = c;
} }
} }
void strrev64(char* str) {
int c, i, j;
for (i = 0, j = strlen64(str)-1; i < j; i++, j--) {
c = str[i];
str[i] = str[j];
str[j] = c;
}
}
uint8_t uitoa32(uint32_t x, char* str) { uint8_t uitoa32(uint32_t x, char* str) {
if (x == 0) {
str[0] = '0';
str[1] = 0;
return 1;
}
uint8_t i=0; uint8_t i=0;
while (x > 0) { while (x > 0) {
str[i++] = x%10+'0'; str[i++] = x%10+'0';
@@ -24,6 +43,22 @@ uint8_t uitoa32(uint32_t x, char* str) {
strrev32(str); strrev32(str);
return i; return i;
} }
uint8_t uitoa64(uint64_t x, char* str) {
if (x == 0) {
str[0] = '0';
str[1] = 0;
return 1;
}
uint8_t i=0;
while (x > 0) {
str[i++] = x%10+'0';
x /= 10;
}
str[i] = 0;
strrev64(str);
return i;
}
void memcopy(void* dest, void* src, size_t size) { void memcopy(void* dest, void* src, size_t size) {
for (size_t i=0;i<size;i++) { for (size_t i=0;i<size;i++) {
((uint8_t*)dest)[i] = *(uint8_t*)src++; ((uint8_t*)dest)[i] = *(uint8_t*)src++;
@@ -58,4 +93,24 @@ void memset(void* dest, size_t size, uint8_t value) {
} }
void strcon(char* x, char* y) { void strcon(char* x, char* y) {
memcopy(x+strlen32(x),y,strlen32(y)+1); memcopy(x+strlen32(x),y,strlen32(y)+1);
}
void uiprint64(uint64_t x, void* func) {
char temp[32];
uitoa64(x, temp);
((void(*)(char*))func)(temp);
}
void memmove(void* dest, void* src, size_t size) { // credit goes to https://github.com/gcc-mirror/gcc/blob/master/libgcc/memmove.c, slightly modified for readability for myself.
char *d = dest;
const char *s = src;
if (d < s) {
while (size--) {
*d++ = *s++;
}
} else {
char *lasts = s + (size-1);
char *lastd = d + (size-1);
while (size--) {
*lastd-- = *lasts--;
}
}
} }

View File

@@ -6,11 +6,9 @@ virtualConsole consoles[consolesAmount];
uint8_t currentConsole = 0; uint8_t currentConsole = 0;
void con_dummyrend(virtualConsole* con) {} void con_dummyrend(virtualConsole* con) {}
void con_kputchar(virtualConsole* con, char x, uint8_t newrender) { void con_kputchar(virtualConsole* con, char x, uint8_t newrender) {
if (con->kstdout_count == 8192) { while ((con->kstdout_count) > (CON_sizex*CON_sizey)) {
for (uint32_t i=0;i<8191;i++) {
con->kstdout[i] = con->kstdout[i+1];
}
con->kstdout_count --; con->kstdout_count --;
memcopy(con->kstdout, con->kstdout+1, con->kstdout_count);
} }
con->kstdout[con->kstdout_count++] = x; con->kstdout[con->kstdout_count++] = x;
if (newrender && &consoles[currentConsole] == con && con->enableRendering) { if (newrender && &consoles[currentConsole] == con && con->enableRendering) {
@@ -50,4 +48,26 @@ void con_render() {
} else { } else {
kpanic("virtualConsole failure:\nFU_kupdbuf is 0x00."); kpanic("virtualConsole failure:\nFU_kupdbuf is 0x00.");
} }
}
void con_putkey(virtualConsole* con, uint16_t key) {
if (con->keyBufSize < 1024) {
con->keyBuf[con->keyBufSize++] = key;
}
}
uint16_t con_popkey(virtualConsole* con) {
if (con->keyBufSize == 0) {
return 0x0000;
}
uint16_t out = con->keyBuf[0];
memmove(&con->keyBuf[0], &con->keyBuf[1], 1023);
return out;
}
uint8_t con_iskeyavail(virtualConsole* con) {
return con->keyBufSize > 0;
}
uint16_t con_gettopkey(virtualConsole* con) {
if (con->keyBufSize == 0) {
return 0x0000;
}
return con->keyBuf[0];
} }

14
src/memManager/header.h Normal file
View File

@@ -0,0 +1,14 @@
#include "../headers/stddef.h"
#include "../headers/memMap.h"
extern void* MEM_pagalloc;
extern void* MEM_pagfree;
typedef struct {
void* prev;
size_t size;
void* next;
} MEM_tag;
extern void* malloc(size_t);
extern void free(void*);

94
src/memManager/src.c Normal file
View File

@@ -0,0 +1,94 @@
#include "header.h"
void* MEM_pagalloc = 0x00;
void* MEM_pagfree = 0x00;
uint8_t pagealloc(MEM_tag** addr, size_t amount) {
if (MEM_pagalloc != 0x00) {
uint8_t suc;
void* ptr = ((void* (*)(size_t, uint8_t*))MEM_pagalloc)(amount, &suc);
if (!suc) {return 1;}
*addr = ptr;
return 0;
}
return 1;
}
void pagefree(void* addr, size_t amount) {
if (MEM_pagfree != 0x00) {
((void (*)(void*, size_t))MEM_pagfree)(addr, amount);
}
}
inline size_t getTotalBytesAmount(size_t bytes) {
return bytes+sizeof(MEM_tag);
}
inline size_t getTotalPagesAmount(size_t bytes) {
return getTotalBytesAmount(bytes)/PAGE_SIZE + (getTotalBytesAmount(bytes)%PAGE_SIZE > 0 ? 1 : 0);
}
MEM_tag* memprim = 0x00;
// does this remind you of a linked list, ya?
void* malloc(size_t bytes) {
if (memprim == 0x00) { // we have to allocate the primary memory thing first.
if (pagealloc(&memprim, getTotalPagesAmount(bytes))) {
return (void*)0x00;
}
memprim->size = getTotalBytesAmount(bytes);
memprim->next = 0x00;
memprim->prev = 0x00;
return (void*)((size_t)memprim+sizeof(MEM_tag));
}
// if we are here, we find the "topmost" memory tag first.
MEM_tag* topmost = memprim;
while (1) { // simple as that.
if (topmost->next == 0x00) {
break;
} else {
topmost = topmost->next;
}
}
MEM_tag* newtag;
if (pagealloc(&newtag, getTotalPagesAmount(bytes))) {
return (void*)0x00;
}
newtag->prev = topmost;
newtag->next = 0x00;
topmost->next = newtag;
newtag->size = getTotalBytesAmount(bytes);
return (void*)((size_t)newtag+sizeof(MEM_tag));
}
void free(void* address) {
if (memprim == 0x00) {return;}
// find the tag associated with the address.
MEM_tag* tag = memprim;
while (1) {
if ((size_t)tag+sizeof(MEM_tag) == address) { // this is the tag.
if (tag->next != 0x00) {
if (tag->prev != 0x00) {
((MEM_tag*)tag->next)->prev = tag->prev;
} else {
((MEM_tag*)tag->next)->prev = 0x00;
memprim = tag->next;
}
}
if (tag->prev != 0x00) {
if (tag->next != 0x00) {
((MEM_tag*)tag->prev)->next = tag->next;
} else {
((MEM_tag*)tag->prev)->next = 0x00;
}
} else { // since prev is 0x00 we must be memprim (except something messed with our tag.)
memprim = 0x00;
}
pagefree(tag, getTotalPagesAmount(tag->size-sizeof(MEM_tag)));
return;
}
if (tag->next != 0x00) {
tag = tag->next;
} else {
return;
}
}
}