This commit is contained in:
Nicholas Orlowsky 2025-02-28 21:25:17 -05:00
parent ce2b373313
commit 9114529153
46 changed files with 126016 additions and 125522 deletions

17
kernel/drivers/blk/blk.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
struct block_dev {
char name[16];
uint32_t sector_size;
uint32_t device_no;
uint32_t num_sectors;
uint32_t (*read_sector)(uint32_t, uint32_t, char *);
uint32_t (*write_sector)(uint32_t, uint32_t, char *);
};
void BLK__init();
uint32_t BLK__register_device(struct block_dev*);
uint32_t BLK__get_block_devices(struct block_dev* devices, uint32_t req_num);
uint32_t BLK__get_block_device(struct block_dev* devices, uint32_t req_num);

View file

@ -0,0 +1,45 @@
#include "./ramblk.h"
#include "../../../memory/memory.h"
#include "../blk.h"
#define RAMFS_BYTES (1024 * 1024 * 5) // 5 MB
#define SECTOR_SIZE (512)
char ramfs_blocks[RAMFS_BYTES];
uint32_t RAMBLK__read_sector(uint32_t device, uint32_t sector, char *out) {
if (sector * SECTOR_SIZE >= RAMFS_BYTES) {
// Out of bounds
return 0;
}
uint32_t byte = sector * SECTOR_SIZE;
memcpy(ramfs_blocks + byte, out, SECTOR_SIZE);
return 1;
}
uint32_t RAMBLK__write_sector(uint32_t device, uint32_t sector, char *in) {
if ((sector + 1) * SECTOR_SIZE >= RAMFS_BYTES) {
// Out of bounds
return 0;
}
uint32_t byte = sector * SECTOR_SIZE;
memcpy(in, ramfs_blocks + byte, SECTOR_SIZE);
return 1;
}
void RAMBLK__init() {
memset(ramfs_blocks, 0x00, RAMFS_BYTES);
struct block_dev bd = {
.name = "RAM_BLK",
.sector_size = SECTOR_SIZE,
.device_no = 0,
.num_sectors = RAMFS_BYTES / SECTOR_SIZE,
.read_sector = &RAMBLK__read_sector,
.write_sector = &RAMBLK__write_sector
};
BLK__register_device(&bd);
}

View file

@ -0,0 +1,7 @@
#pragma once
#include <inttypes.h>
void RAMBLK__init();
uint32_t RAMBLK__read_sector(uint32_t device, uint32_t sector, char *out);
uint32_t RAMBLK__write_sector(uint32_t device, uint32_t sector, char *in);

View file

@ -0,0 +1,208 @@
// Nick's Quick(ly made) File System
#include "nqfs.h"
#include "../../../io/io.h"
#include "../../../memory/memory.h"
#define FILEPTR_SECTORS (128)
#define FILEPTR_PER_SECTOR (4)
#define FILEPTR_CNT (FILEPTR_SECTORS * FILEPTR_PER_SECTOR)
void NQFS_init() {}
uint32_t NQFS_get_next_free_block(struct block_dev *device) {
char sector[512];
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)sector;
for (uint32_t i = FILEPTR_SECTORS; i < device->num_sectors; ++i) {
if (!device->read_sector(device->device_no, i, sector)) {
return 0;
}
if (sb->magic_number != 0xC001) {
sb->magic_number = 0xC001;
sb->next_sector = 0;
if (!device->write_sector(device->device_no, i, sector)) {
return 0;
}
return i;
}
}
return 0;
}
uint32_t NQFS_create_file(struct block_dev *device, char *filename) {
char sector[512];
for (int i = 0; i < FILEPTR_SECTORS; ++i) {
if (!device->read_sector(device->device_no, i, sector)) {
return 0;
}
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
for (int j = 0; j < FILEPTR_PER_SECTOR; ++j) {
if (!fp->allocd) {
uint32_t new_sector = NQFS_get_next_free_block(device);
if (new_sector == 0) {
return 0;
}
fp->allocd = 1;
fp->size = 0;
fp->start_sector = new_sector;
strncpy(filename, fp->filename, NQFS_MAX_FILENAME_SIZE);
fp->filename[NQFS_MAX_FILENAME_SIZE - 1] = '\0';
if (!device->write_sector(device->device_no, i, sector)) {
return 0;
}
printf_nolock("Created file \"%s\" at sector %d fp %d\n", fp->filename,
new_sector, i);
return i;
}
fp++;
}
}
return 0;
}
uint32_t NQFS_read_bytes(struct block_dev *device, uint32_t inode_sector,
char *out, uint32_t size) {
char sector[512];
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
if (!device->read_sector(device->device_no, inode_sector, sector)) {
return 0;
}
char storage_sector[512];
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)storage_sector;
if (fp->start_sector != 0) {
uint32_t read_sector = fp->start_sector;
if (size > fp->size) {
size = fp->size;
}
while (size > 0) {
if (!device->read_sector(device->device_no, read_sector,
storage_sector)) {
return 0;
}
uint32_t readable = NQFS_STORAGE_BYTES_SECTOR;
if (size < readable) {
readable = size;
}
// Copy data into struct
memcpy(sb->data, out, readable);
out += readable;
size -= readable;
if (size > 0) {
read_sector = sb->next_sector;
if (read_sector == 0) {
return size;
}
}
}
return size;
} else {
printf_nolock("didn't find start\n");
return 0;
}
}
uint32_t NQFS_write_bytes(struct block_dev *device, uint32_t inode_sector,
char *in, uint32_t size) {
uint32_t total_written = 0;
char sector[512];
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
if (!device->read_sector(device->device_no, inode_sector, sector)) {
return 0;
}
char storage_sector[512];
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)storage_sector;
if (fp->start_sector != 0) {
uint32_t cur_size = fp->size;
uint32_t read_sector = fp->start_sector;
while (cur_size >= NQFS_STORAGE_BYTES_SECTOR) {
if (!device->read_sector(device->device_no, read_sector,
storage_sector)) {
return 0;
}
cur_size -= NQFS_STORAGE_BYTES_SECTOR;
read_sector = sb->next_sector;
if (read_sector == 0) {
sb->next_sector = NQFS_get_next_free_block(device);
read_sector = sb->next_sector;
if (read_sector == 0) {
return 0;
}
}
}
while (size > 0) {
if (!device->read_sector(device->device_no, read_sector,
storage_sector)) {
return 0;
}
uint32_t writeable = NQFS_STORAGE_BYTES_SECTOR - cur_size;
if (size < writeable) {
writeable = size;
}
// Copy data into struct
memcpy(in + total_written, sb->data + cur_size, writeable);
cur_size = 0;
fp->size += writeable;
total_written += writeable;
if (!device->write_sector(device->device_no, inode_sector, sector)) {
return 0;
}
// Write struct out to disk
if (!device->write_sector(device->device_no, read_sector,
storage_sector)) {
return 0;
}
size -= writeable;
if (size > 0) {
sb->next_sector = NQFS_get_next_free_block(device);
// Write struct out to disk
if (!device->write_sector(device->device_no, read_sector,
storage_sector)) {
return 0;
}
read_sector = sb->next_sector;
if (read_sector == 0) {
return 0;
}
}
}
} else {
printf_nolock("File didn't point to a storage block\n");
return 0;
}
return total_written;
}
void NQFS_DEBUG_list_files(struct block_dev *device) {
char sector[512];
for (int i = 0; i < FILEPTR_SECTORS; ++i) {
if (!device->read_sector(device->device_no, i, sector)) {
printf_nolock("Error reading sector %d\n", i);
return;
}
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
for (int j = 0; j < FILEPTR_PER_SECTOR; ++j) {
if (fp->allocd) {
printf_nolock("Found file: %s\n", fp->filename);
}
fp++;
}
}
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "../../blk/blk.h"
#include <stdint.h>
#define NQFS_MAX_FILENAME_SIZE (64)
#define NQFS_STORAGE_BYTES_SECTOR (504)
struct NQFS_inode {
uint8_t allocd;
char filename[NQFS_MAX_FILENAME_SIZE];
uint32_t start_sector;
uint32_t size;
char _[55];
} __attribute__((packed));
struct NQFS_storage_block {
uint32_t magic_number;
char data[NQFS_STORAGE_BYTES_SECTOR];
uint32_t next_sector;
} __attribute__((packed));
uint32_t NQFS_get_next_free_inode(struct block_dev *device);
uint32_t NQFS_create_file(struct block_dev *device, char *filename);
// Returns number of bytes read into char
uint32_t NQFS_read_bytes(struct block_dev *device, uint32_t inode_sector,
char *out, uint32_t max_size);
uint32_t NQFS_write_bytes(struct block_dev *device, uint32_t inode_sector,
char *in, uint32_t size);
void NQFS_DEBUG_list_files(struct block_dev *device);

296
kernel/drivers/ps2/ps2.c Normal file
View file

@ -0,0 +1,296 @@
#include "./ps2.h"
struct ps2_waiter_t ps2_waiters[MAX_PROCESSES];
enum key_code_t {
backtick_tilde = 1,
one_bang = 2,
two_at = 3,
three_crunch = 4,
four_dollar = 5,
five_percent = 6,
six_carat = 7,
seven_amp = 8,
eight_star = 9,
nine_lparen = 10,
zero_rparen = 11,
minus_underscore = 12,
equal_plus = 13,
backspace = 14,
tab = 15,
lbracket_lbrace = 26,
rbracket_rbrace = 27,
backslash_pipe = 43,
caps_lock = 58,
semicolon_colon = 39,
quote_dquote = 40,
a = 30,
b = 48,
c = 46,
d = 32,
e = 18,
f = 33,
g = 34,
h = 35,
i = 23,
j = 36,
k = 37,
l = 38,
m = 50,
n = 49,
o = 24,
p = 25,
q = 16,
r = 19,
s = 31,
t = 20,
u = 22,
v = 47,
w = 17,
x = 45,
y = 21,
z = 44,
space = 57,
l_shift = 42,
r_shift = 54,
period_rarr = 52,
enter = 28,
comma_larr = 51,
slash_question = 53
};
struct key_event_t {
enum key_code_t key;
uint8_t is_down;
};
struct kb_state {
uint8_t l_shift;
uint8_t r_shift;
uint8_t l_ctrl;
uint8_t r_ctrl;
uint8_t caps;
};
static struct kb_state kstate;
uint8_t is_shifted() { return kstate.caps | kstate.r_shift | kstate.l_shift; }
char keycode_to_char(enum key_code_t key_code) {
switch (key_code) {
case a:
return is_shifted() ? 'A' : 'a';
break;
case b:
return is_shifted() ? 'B' : 'b';
break;
case c:
return is_shifted() ? 'C' : 'c';
break;
case d:
return is_shifted() ? 'D' : 'd';
break;
case e:
return is_shifted() ? 'E' : 'e';
break;
case f:
return is_shifted() ? 'F' : 'f';
break;
case g:
return is_shifted() ? 'G' : 'g';
break;
case h:
return is_shifted() ? 'H' : 'h';
break;
case i:
return is_shifted() ? 'I' : 'i';
break;
case j:
return is_shifted() ? 'J' : 'j';
break;
case k:
return is_shifted() ? 'K' : 'k';
break;
case l:
return is_shifted() ? 'L' : 'l';
break;
case m:
return is_shifted() ? 'M' : 'm';
break;
case n:
return is_shifted() ? 'N' : 'n';
break;
case o:
return is_shifted() ? 'O' : 'o';
break;
case p:
return is_shifted() ? 'P' : 'p';
break;
case q:
return is_shifted() ? 'Q' : 'q';
break;
case r:
return is_shifted() ? 'R' : 'r';
break;
case s:
return is_shifted() ? 'S' : 's';
break;
case t:
return is_shifted() ? 'T' : 't';
break;
case u:
return is_shifted() ? 'U' : 'u';
break;
case v:
return is_shifted() ? 'V' : 'v';
break;
case w:
return is_shifted() ? 'W' : 'w';
break;
case x:
return is_shifted() ? 'X' : 'x';
break;
case y:
return is_shifted() ? 'Y' : 'y';
break;
case z:
return is_shifted() ? 'Z' : 'z';
break;
case space:
return ' ';
break;
case comma_larr:
return is_shifted() ? '<' : ',';
break;
case period_rarr:
return is_shifted() ? '>' : '.';
break;
case enter:
return '\n';
break;
case backspace:
return '\b';
break;
case backtick_tilde:
return is_shifted() ? '~' : '`';
break;
case one_bang:
return is_shifted() ? '!' : '1';
break;
case two_at:
return is_shifted() ? '@' : '2';
break;
case three_crunch:
return is_shifted() ? '#' : '3';
break;
case four_dollar:
return is_shifted() ? '$' : '4';
break;
case five_percent:
return is_shifted() ? '%' : '5';
break;
case six_carat:
return is_shifted() ? '^' : '6';
break;
case seven_amp:
return is_shifted() ? '&' : '7';
break;
case eight_star:
return is_shifted() ? '*' : '8';
break;
case nine_lparen:
return is_shifted() ? '(' : '9';
break;
case zero_rparen:
return is_shifted() ? ')' : '0';
break;
case minus_underscore:
return is_shifted() ? '_' : '-';
break;
case equal_plus:
return is_shifted() ? '+' : '=';
break;
case tab:
return '\t';
break;
case lbracket_lbrace:
return is_shifted() ? '{' : '[';
break;
case rbracket_rbrace:
return is_shifted() ? '}' : ']';
break;
case semicolon_colon:
return is_shifted() ? ':' : ';';
break;
case quote_dquote:
return is_shifted() ? '"' : '\'';
break;
case backslash_pipe:
return is_shifted() ? '|' : '\\';
break;
case slash_question:
return is_shifted() ? '?' : '/';
break;
case caps_lock:
case r_shift:
case l_shift:
break;
// default:
// printf("%d", key_code);
// break;
}
return '\0';
}
void init_ps2() {
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
ps2_waiters[i].alloc = 0;
}
}
void handle_keypress_char(char c) {
if (c != '\0') {
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
if (ps2_waiters[i].alloc) {
process_table[ps2_waiters[i].pid].registers.eax = c;
ps2_waiters[i].alloc = 0;
process_table[ps2_waiters[i].pid].state = TASKSTATE_ready;
}
}
}
}
void handle_keypress(uint8_t char_code) {
struct key_event_t event;
if ((char_code & 0b11000000) == 0b10000000) {
event.is_down = 0;
event.key = char_code & 0b00111111;
} else {
event.is_down = 1;
event.key = char_code;
}
switch (event.key) {
case l_shift:
kstate.l_shift = event.is_down;
break;
case r_shift:
kstate.r_shift = event.is_down;
break;
case caps_lock:
if (event.is_down) {
kstate.caps = !kstate.caps;
}
break;
default: {
if (event.is_down) {
char c = keycode_to_char(event.key);
handle_keypress_char(c);
}
break;
}
}
}

16
kernel/drivers/ps2/ps2.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
#include "../../scheduler/scheduler.h"
struct ps2_waiter_t {
uint8_t alloc;
uint32_t pid;
};
extern struct ps2_waiter_t ps2_waiters[MAX_PROCESSES];
void init_ps2();
void handle_keypress_char(char);
void handle_keypress(uint8_t);

View file

@ -1,36 +0,0 @@
#pragma once
#include "../../arch/i386/asm.c"
#define COM1 (0x3F8)
int serial_init() {
outb(COM1 + 1, 0x01);
outb(COM1 + 3, 0x80);
outb(COM1 + 0, 0x03);
outb(COM1 + 1, 0x00);
outb(COM1 + 3, 0x03);
outb(COM1 + 2, 0xC7);
outb(COM1 + 4, 0x0B);
outb(COM1 + 4, 0x0F);
return 0;
}
int serial_has_tx() {
return inb(COM1 + 5) & 0x20;
}
int serial_has_rx() {
return inb(COM1 + 5) & 1;
}
void serial_tx(char a) {
while (serial_has_tx() == 0);
outb(COM1,a);
}
char serial_rx() {
while (serial_has_rx() == 0);
return inb(COM1);
}

View file

@ -0,0 +1,36 @@
#pragma once
#include "serial.h"
#include "../../../arch/i386/asm/asm.h"
#define COM1 (0x3F8)
int serial_init() {
outb(COM1 + 1, 0x01);
outb(COM1 + 3, 0x80);
outb(COM1 + 0, 0x03);
outb(COM1 + 1, 0x00);
outb(COM1 + 3, 0x03);
outb(COM1 + 2, 0xC7);
outb(COM1 + 4, 0x0B);
outb(COM1 + 4, 0x0F);
return 0;
}
int serial_has_tx() { return inb(COM1 + 5) & 0x20; }
int serial_has_rx() { return inb(COM1 + 5) & 1; }
void serial_tx(char a) {
while (serial_has_tx() == 0)
;
outb(COM1, a);
}
char serial_rx() {
while (serial_has_rx() == 0)
;
return inb(COM1);
}

View file

@ -0,0 +1,5 @@
#pragma once
int serial_init();
void serial_tx(char);
char serial_rx();

109
kernel/drivers/vga/vga.c Normal file
View file

@ -0,0 +1,109 @@
#pragma once
#include "vga.h"
#include "../../memory/memory.h"
#include <stdint.h>
#define WIDTH 80
#define HEIGHT 25
static char vga_buf[HEIGHT * (WIDTH * 2)];
static uint8_t vgabuf_col = 0;
static uint8_t vgabuf_row = 0;
static uint8_t vgabuf_start_row = 0;
static uint8_t vgabuf_move_row = 0;
static uint8_t default_color_code = 10;
static char *vram = (char *)0xb8000;
static inline int VGA_idx(int row, int col) {
return (row * WIDTH * 2) + (col * 2);
}
static inline void VGA_set(int row, int col, char c, int color_code) {
vga_buf[VGA_idx(row, col)] = c;
vga_buf[VGA_idx(row, col) + 1] = color_code;
}
void VGA_flush() {
int topwrite = ((HEIGHT - vgabuf_start_row) * WIDTH * 2);
// Fill the top of the display from the offsetted buffer
memcpy(vga_buf + (vgabuf_start_row * WIDTH * 2), vram, topwrite);
// Fill the bottom of the display from the offsetted buffer
memcpy(vga_buf, vram + topwrite, ((vgabuf_start_row)*WIDTH * 2));
}
void VGA_clear_screen() {
for (int r = 0; r < HEIGHT - 1; r++) {
for (int c = 0; c < WIDTH; c++) {
VGA_set(r, c, ' ', default_color_code);
}
}
vgabuf_start_row = 0;
vgabuf_col = 0;
vgabuf_row = 0;
VGA_flush();
}
void VGA_clear_line() {
for (int i = 0; i < WIDTH; ++i) {
VGA_set(vgabuf_start_row, i, ' ', default_color_code);
}
}
void VGA_putc(char c) {
if (vgabuf_col == WIDTH) {
vgabuf_row = (vgabuf_row + 1) % HEIGHT;
vgabuf_col = 0;
if (vgabuf_start_row > 0 || vgabuf_row == 0) {
if (vgabuf_move_row == vgabuf_start_row) {
vgabuf_start_row = (vgabuf_start_row + 1) % HEIGHT;
vgabuf_move_row = vgabuf_start_row;
} else {
vgabuf_move_row++;
}
VGA_clear_line();
}
}
if (c == '\n') {
for (int i = vgabuf_col; i < WIDTH; i++) {
VGA_set(vgabuf_row, i, ' ', default_color_code);
}
vgabuf_row = (vgabuf_row + 1) % HEIGHT;
vgabuf_col = 0;
if (vgabuf_start_row > 0 || vgabuf_row == 0) {
if (vgabuf_move_row == vgabuf_start_row) {
vgabuf_start_row = (vgabuf_start_row + 1) % HEIGHT;
vgabuf_move_row = vgabuf_start_row;
} else {
vgabuf_move_row++;
}
VGA_clear_line();
}
return;
}
if (c == '\b') {
if (vgabuf_col == 0) {
vgabuf_col = WIDTH - 1;
vgabuf_row--;
vgabuf_move_row--;
} else {
vgabuf_col--;
}
// VGA_set(vgabuf_row, vgabuf_col, ' ', default_color_code);
return;
}
VGA_set(vgabuf_row, vgabuf_col, c, default_color_code);
vgabuf_col++;
}

5
kernel/drivers/vga/vga.h Normal file
View file

@ -0,0 +1,5 @@
#pragma once
void VGA_clear_screen();
void VGA_putc(char);
void VGA_flush();