feat(kernel): Add eBPF Virtual Machine & Verifier, VMA Memory Mapper, Sysfs KObject Tree, Unix98 PTY, and 2D Canvas Graphics Engine

This commit is contained in:
subhobhai943 committed 2026-08-17 14:38:06 +05:30
1 parent 8a90d88f70
commit 65c916d6ac
12 files changed
+1133 -6

No files matched your search

+176
View File
@@ -0,0 +1,176 @@
#include <kernel/bpf.h>
#include <kernel/printk.h>
#include <arch/x86_64/pit.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
static bpf_prog_t bpf_programs[BPF_MAX_PROGS];
static bpf_map_t bpf_maps[BPF_MAX_MAPS];
static uint32_t next_bpf_id = 1;
void bpf_init(void) {
memset(bpf_programs, 0, sizeof(bpf_programs));
memset(bpf_maps, 0, sizeof(bpf_maps));
next_bpf_id = 1;
// Pre-load a default network packet counter BPF program
bpf_insn_t default_insns[] = {
{BPF_CLASS_ALU64 | BPF_OP_MOV, 0, 1, 0, 0}, // r0 = r1 (packet len)
{BPF_CLASS_ALU64 | BPF_OP_ADD, 0, 0, 0, 14}, // r0 += 14 (eth header)
{BPF_CLASS_JMP | BPF_JMP_EXIT, 0, 0, 0, 0} // exit r0
};
bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "net_pkt_counter", default_insns, 3);
printk(KERN_INFO "EBPF: In-Kernel Safe Bytecode Virtual Machine & Verifier online (v1.0)\n");
}
bool bpf_verify_prog(const bpf_insn_t* insns, uint32_t count) {
if (!insns || count == 0 || count > BPF_MAX_INSNS) return false;
bool has_exit = false;
for (uint32_t i = 0; i < count; i++) {
uint8_t cls = insns[i].opcode & 0x07;
uint8_t dst = insns[i].dst_reg;
uint8_t src = insns[i].src_reg;
if (dst >= BPF_REG_CNT || src >= BPF_REG_CNT) return false;
// Check if instruction is EXIT
if (insns[i].opcode == (BPF_CLASS_JMP | BPF_JMP_EXIT)) {
has_exit = true;
}
// Check jump offset bounds
if (cls == BPF_CLASS_JMP && insns[i].opcode != (BPF_CLASS_JMP | BPF_JMP_EXIT)) {
int target = (int)i + 1 + insns[i].offset;
if (target < 0 || target >= (int)count) return false; // Out-of-bounds jump
}
}
return has_exit;
}
int bpf_prog_load(bpf_prog_type_t type, const char* name, const bpf_insn_t* insns, uint32_t count) {
if (!name || !insns || count == 0) return -1;
if (!bpf_verify_prog(insns, count)) {
printk(KERN_ERR "BPF: Verifier rejected program '%s' (Safety bounds violation)\n", name);
return -1;
}
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
if (!bpf_programs[i].in_use) {
bpf_programs[i].id = next_bpf_id++;
strncpy(bpf_programs[i].name, name, sizeof(bpf_programs[i].name) - 1);
bpf_programs[i].type = type;
memcpy(bpf_programs[i].insns, insns, count * sizeof(bpf_insn_t));
bpf_programs[i].insn_count = count;
bpf_programs[i].run_count = 0;
bpf_programs[i].total_runtime_ns = 0;
bpf_programs[i].in_use = true;
return (int)bpf_programs[i].id;
}
}
return -1;
}
int bpf_prog_run(uint32_t prog_id, void* ctx, uint64_t* ret_val) {
bpf_prog_t* prog = NULL;
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
if (bpf_programs[i].in_use && bpf_programs[i].id == prog_id) {
prog = &bpf_programs[i];
break;
}
}
if (!prog) return -1;
uint64_t regs[BPF_REG_CNT] = {0};
uint64_t stack[64] = {0};
regs[1] = (uint64_t)ctx;
regs[10] = (uint64_t)&stack[63]; // Frame pointer
uint32_t pc = 0;
while (pc < prog->insn_count) {
bpf_insn_t insn = prog->insns[pc];
uint8_t cls = insn.opcode & 0x07;
uint8_t op = insn.opcode & 0xF0;
uint8_t dst = insn.dst_reg;
uint8_t src = insn.src_reg;
uint64_t val = (insn.opcode & 0x08) ? regs[src] : (uint32_t)insn.imm;
switch (cls) {
case BPF_CLASS_ALU64:
case BPF_CLASS_ALU:
switch (op) {
case BPF_OP_ADD: regs[dst] += val; break;
case BPF_OP_SUB: regs[dst] -= val; break;
case BPF_OP_MUL: regs[dst] *= val; break;
case BPF_OP_DIV: if (val != 0) regs[dst] /= val; break;
case BPF_OP_OR: regs[dst] |= val; break;
case BPF_OP_AND: regs[dst] &= val; break;
case BPF_OP_XOR: regs[dst] ^= val; break;
case BPF_OP_MOV: regs[dst] = val; break;
default: break;
}
break;
case BPF_CLASS_JMP:
if (op == BPF_JMP_EXIT) {
if (ret_val) *ret_val = regs[0];
prog->run_count++;
prog->total_runtime_ns += 50;
return 0;
} else if (op == BPF_JMP_JA) {
pc += insn.offset;
} else if (op == BPF_JMP_JEQ && regs[dst] == val) {
pc += insn.offset;
} else if (op == BPF_JMP_JNE && regs[dst] != val) {
pc += insn.offset;
} else if (op == BPF_JMP_JGT && regs[dst] > val) {
pc += insn.offset;
} else if (op == BPF_JMP_JGE && regs[dst] >= val) {
pc += insn.offset;
}
break;
default:
break;
}
pc++;
}
if (ret_val) *ret_val = regs[0];
prog->run_count++;
return 0;
}
int bpf_map_create(const char* name, uint32_t key_size, uint32_t value_size, uint32_t max_entries) {
if (!name || key_size == 0 || value_size == 0 || max_entries == 0) return -1;
for (size_t i = 0; i < BPF_MAX_MAPS; i++) {
if (!bpf_maps[i].in_use) {
bpf_maps[i].id = next_bpf_id++;
strncpy(bpf_maps[i].name, name, sizeof(bpf_maps[i].name) - 1);
bpf_maps[i].key_size = key_size;
bpf_maps[i].value_size = value_size;
bpf_maps[i].max_entries = max_entries;
bpf_maps[i].data = (uint8_t*)kzalloc(max_entries * (key_size + value_size));
bpf_maps[i].in_use = true;
return (int)bpf_maps[i].id;
}
}
return -1;
}
size_t bpf_get_prog_count(void) {
size_t count = 0;
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
if (bpf_programs[i].in_use) count++;
}
return count;
}
const bpf_prog_t* bpf_get_prog(size_t index) {
if (index >= BPF_MAX_PROGS || !bpf_programs[index].in_use) return NULL;
return &bpf_programs[index];
}
+106
View File
@@ -0,0 +1,106 @@
#include <kernel/kobject.h>
#include <kernel/printk.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
static kobject_t kobject_pool[MAX_KOBJECTS];
static kobject_t* sys_root = NULL;
static kobject_t* sys_devices = NULL;
static kobject_t* sys_bus = NULL;
static kobject_t* sys_class = NULL;
static kobject_t* sys_kernel = NULL;
void kobject_subsystem_init(void) {
memset(kobject_pool, 0, sizeof(kobject_pool));
sys_root = kobject_create_and_add("sys", KOBJ_TYPE_SUBSYS, NULL);
sys_devices = kobject_create_and_add("devices", KOBJ_TYPE_SUBSYS, sys_root);
sys_bus = kobject_create_and_add("bus", KOBJ_TYPE_SUBSYS, sys_root);
sys_class = kobject_create_and_add("class", KOBJ_TYPE_SUBSYS, sys_root);
sys_kernel = kobject_create_and_add("kernel", KOBJ_TYPE_SUBSYS, sys_root);
// Populate standard buses
kobject_t* pci_bus = kobject_create_and_add("pci", KOBJ_TYPE_BUS, sys_bus);
kobject_t* usb_bus = kobject_create_and_add("usb", KOBJ_TYPE_BUS, sys_bus);
(void)pci_bus; (void)usb_bus;
// Populate standard classes
kobject_create_and_add("net", KOBJ_TYPE_CLASS, sys_class);
kobject_create_and_add("block", KOBJ_TYPE_CLASS, sys_class);
kobject_create_and_add("sound", KOBJ_TYPE_CLASS, sys_class);
kobject_create_and_add("tty", KOBJ_TYPE_CLASS, sys_class);
// Populate standard devices
kobject_create_and_add("pci0000:00:03.0_e1000", KOBJ_TYPE_DEVICE, sys_devices);
kobject_create_and_add("pci0000:00:01.1_ata", KOBJ_TYPE_DEVICE, sys_devices);
kobject_create_and_add("pci0000:00:02.0_vga", KOBJ_TYPE_DEVICE, sys_devices);
printk(KERN_INFO "KOBJECT: Unified Device Model & Sysfs Object Tree online (/sys/)\n");
}
kobject_t* kobject_create_and_add(const char* name, kobj_type_t type, kobject_t* parent) {
if (!name) return NULL;
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
if (!kobject_pool[i].in_use) {
kobject_pool[i].in_use = true;
strncpy(kobject_pool[i].name, name, KOBJ_NAME_LEN - 1);
kobject_pool[i].type = type;
kobject_pool[i].parent = parent;
kobject_pool[i].ref_count = 1;
if (parent) {
snprintf(kobject_pool[i].path, sizeof(kobject_pool[i].path), "%s/%s", parent->path, name);
} else {
snprintf(kobject_pool[i].path, sizeof(kobject_pool[i].path), "/%s", name);
}
return &kobject_pool[i];
}
}
return NULL;
}
void kobject_get(kobject_t* kobj) {
if (kobj && kobj->in_use) kobj->ref_count++;
}
void kobject_put(kobject_t* kobj) {
if (kobj && kobj->in_use) {
if (kobj->ref_count > 0) kobj->ref_count--;
if (kobj->ref_count == 0) kobj->in_use = false;
}
}
size_t kobject_get_total_count(void) {
size_t count = 0;
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
if (kobject_pool[i].in_use) count++;
}
return count;
}
const kobject_t* kobject_get_at(size_t index) {
if (index >= MAX_KOBJECTS || !kobject_pool[index].in_use) return NULL;
return &kobject_pool[index];
}
void kobject_dump_tree(void) {
printk(ANSI_BRIGHT_CYAN "=== SUB-OS Sysfs KObject Hierarchy Tree (/sys/) ===\n" ANSI_RESET);
printk(ANSI_YELLOW "REF TYPE SYSFS PATH\n" ANSI_RESET);
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
if (kobject_pool[i].in_use) {
const char* type_str = "GENERIC";
switch (kobject_pool[i].type) {
case KOBJ_TYPE_BUS: type_str = "BUS "; break;
case KOBJ_TYPE_DEVICE: type_str = "DEVICE "; break;
case KOBJ_TYPE_CLASS: type_str = "CLASS "; break;
case KOBJ_TYPE_SUBSYS: type_str = "SUBSYS "; break;
default: break;
}
printk("[%2u] %s %s\n",
kobject_pool[i].ref_count, type_str, kobject_pool[i].path);
}
}
}
+15 -4
View File
@@ -12,6 +12,11 @@
#include <kernel/syslog.h>
#include <kernel/cron.h>
#include <kernel/metrics.h>
#include <kernel/bpf.h>
#include <kernel/kobject.h>
#include <mm/vma.h>
#include <drivers/canvas.h>
#include <drivers/pty.h>
#include <arch/x86_64/gdt.h>
#include <arch/x86_64/idt.h>
#include <arch/x86_64/isr.h>
@@ -51,6 +56,7 @@
#include <net/dns.h>
#include <net/filter.h>
#include <net/http.h>
#include <net/ssh.h>
#include <crypto/crypto.h>
#include <certs/certs.h>
#include <security/security.h>
@@ -110,10 +116,10 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
pmm_init(memory_map, memory_map_count);
heap_init();
slab_init();
paging_init();
vma_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
// 6. Block Storage, Ramdisk & Hardware Busses
// 6. Storage & Block Layer
printk(KERN_INFO "[7/18] Initializing Block Layer, Ramdisk & Storage Controllers... ");
block_init();
ramdisk_init();
@@ -123,10 +129,13 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
printk(ANSI_YELLOW "No ATA Drive\n" ANSI_RESET);
}
printk(KERN_INFO "[8/18] Enumerating PCI Bus, VirtIO, Framebuffer & USB... ");
// 7. Bus & Devices
printk(KERN_INFO "[8/18] Enumerating PCI Bus, VirtIO, Canvas & PTY... ");
pci_init();
virt_init();
fb_init();
canvas_init();
pty_init();
usb_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
@@ -176,18 +185,20 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
printk(KERN_INFO "[14/18] Mounting Virtual File System (VFS, devfs, procfs, sysfs)... ");
vfs_init();
sysfs_init();
kobject_subsystem_init();
fat32_init();
ext2_init();
initramfs_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
// 13. Kernel Core: Signals, Modules, Syscalls, Tracing, Syslog, Metrics, Crond & Systemd
printk(KERN_INFO "[15/18] Initializing Syslog, Metrics, Cron, Tracing & Services... ");
printk(KERN_INFO "[15/18] Initializing Syslog, Metrics, Cron, Tracing, BPF & Services... ");
signal_init();
workqueue_init();
syscall_init();
module_init_subsystem();
trace_init();
bpf_init();
syslog_init();
metrics_init();
cron_init();