Initial commit: SUB-OS 64-Bit Production Monolithic Operating System with LazyBox userland suite

This commit is contained in:
subhobhai943 committed 2026-08-16 21:23:52 +05:30
commit cd9c786d14
88 files changed
+7132

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
#include <drivers/keyboard.h>
#include <drivers/tty.h>
#include <arch/x86_64/isr.h>
#include <arch/x86_64/pic.h>
#include <arch/x86_64/io.h>
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64
#define KEYBOARD_BUFFER_SIZE 128
static volatile uint16_t key_buffer[KEYBOARD_BUFFER_SIZE];
static volatile int buffer_head = 0;
static volatile int buffer_tail = 0;
static bool shift_pressed = false;
static bool ctrl_pressed = false;
static bool alt_pressed = false;
static bool capslock = false;
static bool extended_code = false;
static const char scancode_ascii[128] = {
0, 27, '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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const char scancode_ascii_shift[128] = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static void buffer_enqueue(uint16_t key) {
int next = (buffer_head + 1) % KEYBOARD_BUFFER_SIZE;
if (next != buffer_tail) {
key_buffer[buffer_head] = key;
buffer_head = next;
}
}
static void keyboard_interrupt_handler(registers_t* regs) {
(void)regs;
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
if (scancode == 0xE0) {
extended_code = true;
return;
}
if (scancode & 0x80) { // Key Release
uint8_t released = scancode & 0x7F;
if (released == 0x2A || released == 0x36) shift_pressed = false;
else if (released == 0x1D) ctrl_pressed = false;
else if (released == 0x38) alt_pressed = false;
extended_code = false;
return;
}
// Key Press
if (scancode == 0x2A || scancode == 0x36) { shift_pressed = true; return; }
if (scancode == 0x1D) { ctrl_pressed = true; return; }
if (scancode == 0x38) { alt_pressed = true; return; }
if (scancode == 0x3A) { capslock = !capslock; return; }
// Alt + F1..F4 -> Switch Virtual Consoles
if (alt_pressed) {
if (scancode >= 0x3B && scancode <= 0x3E) { // F1 - F4
tty_switch(scancode - 0x3B);
return;
}
}
if (extended_code) {
extended_code = false;
switch (scancode) {
case 0x48: buffer_enqueue(KEY_UP); return;
case 0x50: buffer_enqueue(KEY_DOWN); return;
case 0x4B: buffer_enqueue(KEY_LEFT); return;
case 0x4D: buffer_enqueue(KEY_RIGHT); return;
case 0x47: buffer_enqueue(KEY_HOME); return;
case 0x4F: buffer_enqueue(KEY_END); return;
case 0x49: buffer_enqueue(KEY_PAGE_UP); return;
case 0x51: buffer_enqueue(KEY_PAGE_DOWN); return;
case 0x52: buffer_enqueue(KEY_INSERT); return;
case 0x53: buffer_enqueue(KEY_DELETE); return;
}
}
// Function Keys F1-F12
if (scancode >= 0x3B && scancode <= 0x44) {
buffer_enqueue(KEY_F1 + (scancode - 0x3B));
return;
}
if (ctrl_pressed) {
if (scancode == 0x2E) { buffer_enqueue(0x03); return; } // Ctrl+C
if (scancode == 0x26) { buffer_enqueue(0x0C); return; } // Ctrl+L
if (scancode == 0x20) { buffer_enqueue(0x04); return; } // Ctrl+D
}
bool use_shift = shift_pressed ^ capslock;
char c = use_shift ? scancode_ascii_shift[scancode] : scancode_ascii[scancode];
if (c) {
buffer_enqueue((uint16_t)c);
}
}
void keyboard_init(void) {
buffer_head = 0;
buffer_tail = 0;
isr_register_handler(33, keyboard_interrupt_handler); // IRQ1
pic_clear_mask(1);
}
bool keyboard_has_key(void) {
return buffer_head != buffer_tail;
}
uint16_t keyboard_get_key(void) {
while (!keyboard_has_key()) {
hlt();
}
uint16_t key = key_buffer[buffer_tail];
buffer_tail = (buffer_tail + 1) % KEYBOARD_BUFFER_SIZE;
return key;
}
char keyboard_get_char(void) {
uint16_t key = keyboard_get_key();
if (key & KEY_SPECIAL_FLAG) return 0;
return (char)(key & 0xFF);
}
+39
View File
@@ -0,0 +1,39 @@
#include <drivers/serial.h>
#include <arch/x86_64/io.h>
void serial_init(void) {
outb(COM1_PORT + 1, 0x00); // Disable all interrupts
outb(COM1_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(COM1_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(COM1_PORT + 1, 0x00); // (hi byte)
outb(COM1_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(COM1_PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(COM1_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
}
static bool serial_is_transmit_empty(void) {
return (inb(COM1_PORT + 5) & 0x20) != 0;
}
void serial_write_char(char c) {
while (!serial_is_transmit_empty());
outb(COM1_PORT, c);
}
void serial_write_string(const char* str) {
while (*str) {
if (*str == '\n') {
serial_write_char('\r');
}
serial_write_char(*str++);
}
}
bool serial_received(void) {
return (inb(COM1_PORT + 5) & 1) != 0;
}
char serial_read_char(void) {
while (!serial_received());
return inb(COM1_PORT);
}
+166
View File
@@ -0,0 +1,166 @@
#include <drivers/tty.h>
#include <drivers/vga.h>
#include <lib/string.h>
typedef struct {
uint16_t buffer[TTY_HEIGHT][TTY_WIDTH];
int cursor_row;
int cursor_col;
uint8_t current_color;
} tty_t;
static tty_t ttys[MAX_TTYS];
static int current_tty = 0;
static volatile uint16_t* const VGA_MEM = (uint16_t*)VGA_MEMORY;
static void tty_render_current(void) {
tty_t* t = &ttys[current_tty];
for (int y = 0; y < TTY_HEIGHT; y++) {
for (int x = 0; x < TTY_WIDTH; x++) {
VGA_MEM[y * TTY_WIDTH + x] = t->buffer[y][x];
}
}
vga_set_cursor(t->cursor_row, t->cursor_col);
}
void tty_switch(int index) {
if (index < 0 || index >= MAX_TTYS) return;
current_tty = index;
tty_render_current();
}
int tty_get_current(void) {
return current_tty;
}
static void tty_scroll(tty_t* t) {
for (int y = 0; y < TTY_HEIGHT - 1; y++) {
for (int x = 0; x < TTY_WIDTH; x++) {
t->buffer[y][x] = t->buffer[y + 1][x];
}
}
for (int x = 0; x < TTY_WIDTH; x++) {
t->buffer[TTY_HEIGHT - 1][x] = vga_entry(' ', t->current_color);
}
t->cursor_row = TTY_HEIGHT - 1;
}
void tty_clear(void) {
tty_t* t = &ttys[current_tty];
for (int y = 0; y < TTY_HEIGHT; y++) {
for (int x = 0; x < TTY_WIDTH; x++) {
t->buffer[y][x] = vga_entry(' ', t->current_color);
}
}
t->cursor_row = 0;
t->cursor_col = 0;
tty_render_current();
}
void tty_set_cursor(int row, int col) {
tty_t* t = &ttys[current_tty];
t->cursor_row = row;
t->cursor_col = col;
vga_set_cursor(row, col);
}
void tty_write(const char* data, size_t size) {
tty_t* t = &ttys[current_tty];
for (size_t i = 0; i < size; i++) {
char c = data[i];
// Basic ANSI escape sequence parser (e.g. \033[31m)
if (c == '\033' && i + 1 < size && data[i + 1] == '[') {
i += 2;
int code = 0;
while (i < size && data[i] >= '0' && data[i] <= '9') {
code = code * 10 + (data[i] - '0');
i++;
}
if (i < size && data[i] == 'm') {
if (code == 0) t->current_color = 0x07; // Reset
else if (code == 31) t->current_color = 0x04; // Red
else if (code == 32) t->current_color = 0x02; // Green
else if (code == 33) t->current_color = 0x06; // Brown/Yellow
else if (code == 34) t->current_color = 0x01; // Blue
else if (code == 35) t->current_color = 0x05; // Magenta
else if (code == 36) t->current_color = 0x03; // Cyan
else if (code == 37) t->current_color = 0x07; // White
else if (code == 90) t->current_color = 0x08; // Bright Black (Dark Grey)
else if (code == 91) t->current_color = 0x0C; // Bright Red
else if (code == 92) t->current_color = 0x0A; // Bright Green
else if (code == 93) t->current_color = 0x0E; // Bright Yellow
else if (code == 94) t->current_color = 0x09; // Bright Blue
else if (code == 95) t->current_color = 0x0D; // Bright Magenta
else if (code == 96) t->current_color = 0x0B; // Bright Cyan
else if (code == 97) t->current_color = 0x0F; // Bright White
} else if (i < size && data[i] == 'K') {
// Clear from cursor to end of line
for (int x = t->cursor_col; x < TTY_WIDTH; x++) {
t->buffer[t->cursor_row][x] = vga_entry(' ', t->current_color);
}
} else if (i < size && data[i] == 'D') {
// Move cursor left
if (t->cursor_col > 0) t->cursor_col--;
} else if (i < size && data[i] == 'C') {
// Move cursor right
if (t->cursor_col < TTY_WIDTH - 1) t->cursor_col++;
}
continue;
}
if (c == '\n') {
t->cursor_col = 0;
if (++t->cursor_row >= TTY_HEIGHT) {
tty_scroll(t);
}
} else if (c == '\r') {
t->cursor_col = 0;
} else if (c == '\t') {
t->cursor_col = (t->cursor_col + 8) & ~7;
if (t->cursor_col >= TTY_WIDTH) {
t->cursor_col = 0;
if (++t->cursor_row >= TTY_HEIGHT) {
tty_scroll(t);
}
}
} else if (c == '\b') {
if (t->cursor_col > 0) {
t->cursor_col--;
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(' ', t->current_color);
}
} else {
t->buffer[t->cursor_row][t->cursor_col] = vga_entry(c, t->current_color);
if (++t->cursor_col >= TTY_WIDTH) {
t->cursor_col = 0;
if (++t->cursor_row >= TTY_HEIGHT) {
tty_scroll(t);
}
}
}
}
tty_render_current();
}
void tty_write_string(const char* data) {
tty_write(data, strlen(data));
}
void tty_init(void) {
vga_init();
for (int i = 0; i < MAX_TTYS; i++) {
ttys[i].cursor_row = 0;
ttys[i].cursor_col = 0;
ttys[i].current_color = 0x07;
for (int y = 0; y < TTY_HEIGHT; y++) {
for (int x = 0; x < TTY_WIDTH; x++) {
ttys[i].buffer[y][x] = vga_entry(' ', 0x07);
}
}
}
current_tty = 0;
tty_render_current();
}
+106
View File
@@ -0,0 +1,106 @@
#include <drivers/vga.h>
#include <arch/x86_64/io.h>
#include <lib/string.h>
static volatile uint16_t* const VGA_BUFFER = (uint16_t*)VGA_MEMORY;
static uint8_t vga_color = 0x07;
static int vga_row = 0;
static int vga_col = 0;
void vga_set_cursor(int row, int col) {
vga_row = row;
vga_col = col;
uint16_t pos = row * VGA_WIDTH + col;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t)(pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
}
void vga_get_cursor(int* row, int* col) {
if (row) *row = vga_row;
if (col) *col = vga_col;
}
void vga_enable_cursor(uint8_t cursor_start, uint8_t cursor_end) {
outb(0x3D4, 0x0A);
outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start);
outb(0x3D4, 0x0B);
outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end);
}
void vga_disable_cursor(void) {
outb(0x3D4, 0x0A);
outb(0x3D5, 0x20);
}
void vga_set_color(enum vga_color fg, enum vga_color bg) {
vga_color = vga_entry_color(fg, bg);
}
void vga_clear(void) {
for (int y = 0; y < VGA_HEIGHT; y++) {
for (int x = 0; x < VGA_WIDTH; x++) {
VGA_BUFFER[y * VGA_WIDTH + x] = vga_entry(' ', vga_color);
}
}
vga_set_cursor(0, 0);
}
static void vga_scroll(void) {
for (int y = 0; y < VGA_HEIGHT - 1; y++) {
for (int x = 0; x < VGA_WIDTH; x++) {
VGA_BUFFER[y * VGA_WIDTH + x] = VGA_BUFFER[(y + 1) * VGA_WIDTH + x];
}
}
for (int x = 0; x < VGA_WIDTH; x++) {
VGA_BUFFER[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = vga_entry(' ', vga_color);
}
vga_row = VGA_HEIGHT - 1;
}
void vga_putc(char c) {
if (c == '\n') {
vga_col = 0;
if (++vga_row >= VGA_HEIGHT) {
vga_scroll();
}
} else if (c == '\r') {
vga_col = 0;
} else if (c == '\t') {
vga_col = (vga_col + 8) & ~7;
if (vga_col >= VGA_WIDTH) {
vga_col = 0;
if (++vga_row >= VGA_HEIGHT) {
vga_scroll();
}
}
} else if (c == '\b') {
if (vga_col > 0) {
vga_col--;
VGA_BUFFER[vga_row * VGA_WIDTH + vga_col] = vga_entry(' ', vga_color);
}
} else {
VGA_BUFFER[vga_row * VGA_WIDTH + vga_col] = vga_entry(c, vga_color);
if (++vga_col >= VGA_WIDTH) {
vga_col = 0;
if (++vga_row >= VGA_HEIGHT) {
vga_scroll();
}
}
}
vga_set_cursor(vga_row, vga_col);
}
void vga_write(const char* str) {
while (*str) {
vga_putc(*str++);
}
}
void vga_init(void) {
vga_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
vga_clear();
vga_enable_cursor(14, 15);
}