mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
Initial commit: SUB-OS 64-Bit Production Monolithic Operating System with LazyBox userland suite
This commit is contained in:
commit
cd9c786d14
88 files changed
+7132
No files matched your search
+112
@@ -0,0 +1,112 @@
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/task.h>
|
||||
#include <arch/x86_64/gdt.h>
|
||||
#include <arch/x86_64/idt.h>
|
||||
#include <arch/x86_64/isr.h>
|
||||
#include <arch/x86_64/pic.h>
|
||||
#include <arch/x86_64/pit.h>
|
||||
#include <arch/x86_64/cpuid.h>
|
||||
#include <arch/x86_64/paging.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <drivers/tty.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <drivers/keyboard.h>
|
||||
#include <drivers/ata.h>
|
||||
#include <drivers/pci.h>
|
||||
#include <drivers/e1000.h>
|
||||
#include <drivers/speaker.h>
|
||||
#include <fs/vfs.h>
|
||||
#include <net/net.h>
|
||||
#include <crypto/crypto.h>
|
||||
#include <userland/lazybox.h>
|
||||
#include <userland/shell.h>
|
||||
|
||||
void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
// 1. Initialize Console & Telemetry Serial Port
|
||||
tty_init();
|
||||
serial_init();
|
||||
printk_init();
|
||||
|
||||
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
|
||||
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit Production Monolithic Kernel v%s (%s)\n" ANSI_RESET, KERNEL_VERSION, KERNEL_ARCH);
|
||||
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
|
||||
|
||||
// 2. CPU Architecture & Interrupt Initialization
|
||||
printk(KERN_INFO "[1/11] Initializing 64-Bit Global Descriptor Table (GDT)... ");
|
||||
gdt_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
printk(KERN_INFO "[2/11] Initializing Interrupt Descriptor Table (IDT & ISRs)... ");
|
||||
idt_init();
|
||||
isr_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
printk(KERN_INFO "[3/11] Remapping Dual 8259A PIC Interrupt Controller... ");
|
||||
pic_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
printk(KERN_INFO "[4/11] Configuring 8254 PIT Timer (100 Hz, 10ms resolution)... ");
|
||||
pit_init(100);
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
printk(KERN_INFO "[5/11] Initializing PS/2 Keyboard Controller Driver... ");
|
||||
keyboard_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 3. Memory Subsystems
|
||||
printk(KERN_INFO "[6/11] Initializing Physical Memory Manager (PMM)...\n");
|
||||
pmm_init(memory_map, memory_map_count);
|
||||
|
||||
printk(KERN_INFO "[7/11] Initializing Kernel Dynamic Heap Allocator (4 MB Pool)... ");
|
||||
heap_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
paging_init();
|
||||
|
||||
// 4. Hardware Storage & Bus Enumeration
|
||||
printk(KERN_INFO "[8/11] Initializing ATA / IDE Hard Disk Controller... ");
|
||||
if (ata_init()) {
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
} else {
|
||||
printk(ANSI_YELLOW "No ATA Drive\n" ANSI_RESET);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "[9/11] Enumerating PCI Bus & Network Device Drivers...\n");
|
||||
pci_init();
|
||||
if (e1000_init()) {
|
||||
printk(ANSI_BRIGHT_GREEN " Intel E1000 Gigabit Ethernet Controller Active\n" ANSI_RESET);
|
||||
net_init();
|
||||
printk(ANSI_BRIGHT_GREEN " IPv4 / ARP / ICMP Network Protocol Stack Online\n" ANSI_RESET);
|
||||
} else {
|
||||
printk(ANSI_YELLOW " No PCI Ethernet Controller detected\n" ANSI_RESET);
|
||||
}
|
||||
|
||||
// 5. Security & Cryptography Engine
|
||||
prng_seed(0, 0);
|
||||
|
||||
// 6. Virtual File System & Task Scheduler
|
||||
printk(KERN_INFO "[10/11] Mounting Virtual File System (VFS, devfs, procfs)... ");
|
||||
vfs_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
printk(KERN_INFO "[11/11] Initializing Preemptive Task Scheduler & LazyBox... ");
|
||||
sched_init();
|
||||
lazybox_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 7. Enable Hardware Interrupts
|
||||
sti();
|
||||
printk(ANSI_BRIGHT_GREEN "[INIT] Hardware interrupts active. System ready for userland!\n" ANSI_RESET);
|
||||
|
||||
tty_clear();
|
||||
|
||||
// 8. Launch Interactive Userland Shell
|
||||
shell_run();
|
||||
|
||||
while (1) {
|
||||
hlt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <kernel/panic.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <drivers/tty.h>
|
||||
#include <arch/x86_64/io.h>
|
||||
|
||||
void panic_with_regs(const char* message, const registers_t* regs) {
|
||||
cli();
|
||||
|
||||
printk("\n" ANSI_BRIGHT_RED "================================================================================" ANSI_RESET "\n");
|
||||
printk(ANSI_BRIGHT_RED " *** KERNEL PANIC - SYSTEM HALTED *** " ANSI_RESET "\n");
|
||||
printk(ANSI_BRIGHT_RED "================================================================================" ANSI_RESET "\n\n");
|
||||
printk(ANSI_BRIGHT_WHITE "Reason: " ANSI_YELLOW "%s" ANSI_RESET "\n\n", message ? message : "Unknown Fault");
|
||||
|
||||
if (regs) {
|
||||
printk(ANSI_BRIGHT_CYAN "CPU Register State (x86_64 AMD64 ABI):" ANSI_RESET "\n");
|
||||
printk(" RIP: %016llx CS: %04llx RFLAGS: %016llx\n", regs->rip, regs->cs, regs->rflags);
|
||||
printk(" RSP: %016llx SS: %04llx RBP: %016llx\n", regs->rsp, regs->ss, regs->rbp);
|
||||
printk(" RAX: %016llx RBX: %016llx RCX: %016llx RDX: %016llx\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
|
||||
printk(" RSI: %016llx RDI: %016llx R8: %016llx R9: %016llx\n", regs->rsi, regs->rdi, regs->r8, regs->r9);
|
||||
printk(" R10: %016llx R11: %016llx R12: %016llx R13: %016llx\n", regs->r10, regs->r11, regs->r12, regs->r13);
|
||||
printk(" R14: %016llx R15: %016llx ERR: %016llx INT: %llu\n", regs->r14, regs->r15, regs->error_code, regs->int_no);
|
||||
}
|
||||
|
||||
printk("\n" ANSI_BRIGHT_YELLOW "Please power off or reset your system." ANSI_RESET "\n");
|
||||
|
||||
while (1) {
|
||||
hlt();
|
||||
}
|
||||
}
|
||||
|
||||
void panic(const char* message) {
|
||||
panic_with_regs(message, NULL);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <kernel/printk.h>
|
||||
#include <drivers/tty.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <lib/printf.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/sync.h>
|
||||
|
||||
#define DMESG_BUFFER_SIZE 65536 // 64 KB Ring Buffer
|
||||
|
||||
static char dmesg_buffer[DMESG_BUFFER_SIZE];
|
||||
static size_t dmesg_head = 0;
|
||||
static size_t dmesg_total = 0;
|
||||
static spinlock_t printk_lock = SPINLOCK_INIT;
|
||||
|
||||
void printk_init(void) {
|
||||
memset(dmesg_buffer, 0, sizeof(dmesg_buffer));
|
||||
dmesg_head = 0;
|
||||
dmesg_total = 0;
|
||||
}
|
||||
|
||||
static void dmesg_append(const char* str, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
dmesg_buffer[dmesg_head] = str[i];
|
||||
dmesg_head = (dmesg_head + 1) % DMESG_BUFFER_SIZE;
|
||||
if (dmesg_total < DMESG_BUFFER_SIZE) {
|
||||
dmesg_total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int vprintk(const char* fmt, va_list args) {
|
||||
char buffer[1024];
|
||||
int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
if (len <= 0) return 0;
|
||||
|
||||
spin_lock(&printk_lock);
|
||||
|
||||
// Skip loglevel prefix if present (e.g. "\0016")
|
||||
const char* display_ptr = buffer;
|
||||
if (buffer[0] == '\001' && buffer[1] >= '0' && buffer[1] <= '7') {
|
||||
display_ptr += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
// 1. Output to active TTY console
|
||||
tty_write(display_ptr, (size_t)len);
|
||||
|
||||
// 2. Output to COM1 serial port for host debugging
|
||||
for (int i = 0; i < len; i++) {
|
||||
serial_write_char(display_ptr[i]);
|
||||
}
|
||||
|
||||
// 3. Store in kernel dmesg ring buffer
|
||||
dmesg_append(display_ptr, (size_t)len);
|
||||
|
||||
spin_unlock(&printk_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
int printk(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = vprintk(fmt, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kprintf(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = vprintk(fmt, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dmesg_dump(void) {
|
||||
spin_lock(&printk_lock);
|
||||
if (dmesg_total < DMESG_BUFFER_SIZE) {
|
||||
tty_write(dmesg_buffer, dmesg_total);
|
||||
} else {
|
||||
// Output from head to end, then 0 to head
|
||||
tty_write(dmesg_buffer + dmesg_head, DMESG_BUFFER_SIZE - dmesg_head);
|
||||
tty_write(dmesg_buffer, dmesg_head);
|
||||
}
|
||||
spin_unlock(&printk_lock);
|
||||
}
|
||||
|
||||
const char* dmesg_get_buffer(size_t* size_out) {
|
||||
if (size_out) *size_out = dmesg_total;
|
||||
return dmesg_buffer;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/sync.h>
|
||||
#include <arch/x86_64/pit.h>
|
||||
|
||||
static struct list_head ready_queue;
|
||||
static spinlock_t sched_lock = SPINLOCK_INIT;
|
||||
|
||||
extern void task_init_idle(void);
|
||||
|
||||
void sched_init(void) {
|
||||
INIT_LIST_HEAD(&ready_queue);
|
||||
task_init_idle();
|
||||
}
|
||||
|
||||
void sched_add_task(task_t* task) {
|
||||
if (!task) return;
|
||||
spin_lock(&sched_lock);
|
||||
list_add_tail(&task->list, &ready_queue);
|
||||
spin_unlock(&sched_lock);
|
||||
}
|
||||
|
||||
void sched_remove_task(task_t* task) {
|
||||
if (!task) return;
|
||||
spin_lock(&sched_lock);
|
||||
list_del(&task->list);
|
||||
spin_unlock(&sched_lock);
|
||||
}
|
||||
|
||||
void sched_yield(void) {
|
||||
// Cooperative yield
|
||||
sched_schedule();
|
||||
}
|
||||
|
||||
void sched_tick(void) {
|
||||
// Timer tick scheduler hook
|
||||
task_t* curr = task_current();
|
||||
if (curr && curr->pid != 0) {
|
||||
if (--curr->time_slice <= 0) {
|
||||
curr->time_slice = 10;
|
||||
sched_schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sched_schedule(void) {
|
||||
spin_lock(&sched_lock);
|
||||
|
||||
if (list_empty(&ready_queue)) {
|
||||
spin_unlock(&sched_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
task_t* next = list_entry(ready_queue.next, task_t, list);
|
||||
list_del(&next->list);
|
||||
list_add_tail(&next->list, &ready_queue); // Move to back of round-robin queue
|
||||
|
||||
task_t* curr = task_current();
|
||||
if (curr != next) {
|
||||
// Context switch logic
|
||||
next->state = TASK_STATE_RUNNING;
|
||||
if (curr->state == TASK_STATE_RUNNING) {
|
||||
curr->state = TASK_STATE_READY;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&sched_lock);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <kernel/sync.h>
|
||||
#include <kernel/sched.h>
|
||||
|
||||
void sem_init(semaphore_t* sem, int value) {
|
||||
spinlock_init(&sem->lock);
|
||||
sem->count = value;
|
||||
}
|
||||
|
||||
void sem_wait(semaphore_t* sem) {
|
||||
while (1) {
|
||||
spin_lock(&sem->lock);
|
||||
if (sem->count > 0) {
|
||||
sem->count--;
|
||||
spin_unlock(&sem->lock);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&sem->lock);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
void sem_post(semaphore_t* sem) {
|
||||
spin_lock(&sem->lock);
|
||||
sem->count++;
|
||||
spin_unlock(&sem->lock);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <kernel/task.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
static pid_t next_pid = 1;
|
||||
static task_t* current_task = NULL;
|
||||
static task_t kernel_idle_task;
|
||||
|
||||
static void task_wrapper(task_entry_fn_t entry, void* arg) {
|
||||
if (entry) {
|
||||
entry(arg);
|
||||
}
|
||||
task_exit(0);
|
||||
}
|
||||
|
||||
task_t* task_create(const char* name, task_entry_fn_t entry, void* arg, int priority) {
|
||||
task_t* task = (task_t*)kzalloc(sizeof(task_t));
|
||||
if (!task) return NULL;
|
||||
|
||||
task->pid = next_pid++;
|
||||
strncpy(task->name, name ? name : "task", sizeof(task->name) - 1);
|
||||
task->state = TASK_STATE_READY;
|
||||
task->priority = priority;
|
||||
task->time_slice = 10; // 10 ticks = 100ms default
|
||||
|
||||
// Allocate 16 KB stack for thread
|
||||
task->stack_size = 16384;
|
||||
task->stack_base = (uint64_t)kmalloc(task->stack_size);
|
||||
if (!task->stack_base) {
|
||||
kfree(task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t* stack_top = (uint64_t*)(task->stack_base + task->stack_size);
|
||||
|
||||
// Set up initial stack frame for AMD64
|
||||
*(--stack_top) = (uint64_t)arg; // RDI (arg)
|
||||
*(--stack_top) = (uint64_t)entry; // RSI (entry function)
|
||||
*(--stack_top) = (uint64_t)task_wrapper; // RIP
|
||||
|
||||
task->rsp = (uint64_t)stack_top;
|
||||
|
||||
INIT_LIST_HEAD(&task->list);
|
||||
sched_add_task(task);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void task_exit(int exit_code) {
|
||||
(void)exit_code;
|
||||
if (current_task && current_task->pid != 0) {
|
||||
current_task->state = TASK_STATE_DEAD;
|
||||
sched_remove_task(current_task);
|
||||
sched_yield();
|
||||
}
|
||||
while (1) {
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
task_t* task_current(void) {
|
||||
return current_task;
|
||||
}
|
||||
|
||||
pid_t task_get_pid(void) {
|
||||
return current_task ? current_task->pid : 0;
|
||||
}
|
||||
|
||||
void task_set_current(task_t* task) {
|
||||
current_task = task;
|
||||
}
|
||||
|
||||
void task_init_idle(void) {
|
||||
memset(&kernel_idle_task, 0, sizeof(task_t));
|
||||
kernel_idle_task.pid = 0;
|
||||
strcpy(kernel_idle_task.name, "swapper/0");
|
||||
kernel_idle_task.state = TASK_STATE_RUNNING;
|
||||
INIT_LIST_HEAD(&kernel_idle_task.list);
|
||||
current_task = &kernel_idle_task;
|
||||
}
|
||||
Reference in new issue
Block a user