trying to make the keyboard driver work, right now I am suffering.
This commit is contained in:
@@ -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 = .;
|
||||||
}
|
}
|
||||||
5
makefile
5
makefile
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
16
src/headers/memMap.h
Normal 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);
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
112
src/kernel/keyboard.c
Normal 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
109
src/kernel/memMap.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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++) {
|
||||||
|
|||||||
@@ -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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
14
src/memManager/header.h
Normal 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
94
src/memManager/src.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user