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

+79
View File
@@ -0,0 +1,79 @@
#include <fs/devfs.h>
#include <fs/ramfs.h>
#include <drivers/tty.h>
#include <crypto/crypto.h>
#include <lib/string.h>
#include <mm/kmalloc.h>
static vfs_node_t* devfs_root = NULL;
static ssize_t dev_null_write(vfs_node_t* node, off_t offset, size_t size, const uint8_t* buffer) {
(void)node; (void)offset; (void)buffer;
return (ssize_t)size; // Discard everything
}
static ssize_t dev_null_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node; (void)offset; (void)size; (void)buffer;
return 0; // EOF immediately
}
static ssize_t dev_zero_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node; (void)offset;
memset(buffer, 0, size);
return (ssize_t)size;
}
static ssize_t dev_random_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node; (void)offset;
prng_get_bytes(buffer, size);
return (ssize_t)size;
}
static ssize_t dev_tty_write(vfs_node_t* node, off_t offset, size_t size, const uint8_t* buffer) {
(void)node; (void)offset;
tty_write((const char*)buffer, size);
return (ssize_t)size;
}
void devfs_init(void) {
devfs_root = ramfs_add_dir(NULL, "dev");
// 1. /dev/null
vfs_node_t* null_dev = ramfs_add_file(devfs_root, "null", NULL, 0);
if (null_dev) {
null_dev->flags = FS_CHARDEVICE;
null_dev->read = dev_null_read;
null_dev->write = dev_null_write;
}
// 2. /dev/zero
vfs_node_t* zero_dev = ramfs_add_file(devfs_root, "zero", NULL, 0);
if (zero_dev) {
zero_dev->flags = FS_CHARDEVICE;
zero_dev->read = dev_zero_read;
zero_dev->write = dev_null_write;
}
// 3. /dev/random & /dev/urandom
vfs_node_t* rand_dev = ramfs_add_file(devfs_root, "random", NULL, 0);
if (rand_dev) {
rand_dev->flags = FS_CHARDEVICE;
rand_dev->read = dev_random_read;
}
vfs_node_t* urand_dev = ramfs_add_file(devfs_root, "urandom", NULL, 0);
if (urand_dev) {
urand_dev->flags = FS_CHARDEVICE;
urand_dev->read = dev_random_read;
}
// 4. /dev/tty
vfs_node_t* tty_dev = ramfs_add_file(devfs_root, "tty", NULL, 0);
if (tty_dev) {
tty_dev->flags = FS_CHARDEVICE;
tty_dev->write = dev_tty_write;
}
}
vfs_node_t* devfs_get_root(void) {
return devfs_root;
}
+142
View File
@@ -0,0 +1,142 @@
#include <fs/procfs.h>
#include <fs/ramfs.h>
#include <arch/x86_64/cpuid.h>
#include <arch/x86_64/pit.h>
#include <mm/pmm.h>
#include <mm/kmalloc.h>
#include <drivers/e1000.h>
#include <lib/printf.h>
#include <lib/string.h>
static vfs_node_t* procfs_root = NULL;
static ssize_t proc_version_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node;
char text[256];
int len = sprintf(text, "SUB-OS version 0.2.0-lts (subhobhai@sub-os) (x86_64-elf-gcc 13.3.0) #1 SMP PREEMPT Sun Aug 16 2026\n");
if (offset >= len) return 0;
if (offset + size > (size_t)len) size = len - offset;
memcpy(buffer, text + offset, size);
return (ssize_t)size;
}
static ssize_t proc_uptime_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node;
uint64_t ticks = pit_get_ticks();
uint64_t secs = ticks / 100;
uint64_t frac = (ticks % 100);
char text[64];
int len = sprintf(text, "%llu.%02llu %llu.%02llu\n", secs, frac, secs, frac);
if (offset >= len) return 0;
if (offset + size > (size_t)len) size = len - offset;
memcpy(buffer, text + offset, size);
return (ssize_t)size;
}
static ssize_t proc_meminfo_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node;
uint64_t total_kb = (pmm_get_total_pages() * 4096) / 1024;
uint64_t free_kb = (pmm_get_free_pages() * 4096) / 1024;
uint64_t used_kb = (pmm_get_used_pages() * 4096) / 1024;
char text[512];
int len = sprintf(text,
"MemTotal: %8llu kB\n"
"MemFree: %8llu kB\n"
"MemAvailable: %8llu kB\n"
"Buffers: 0 kB\n"
"Cached: %8llu kB\n"
"HeapTotal: %8llu kB\n"
"HeapUsed: %8llu kB\n"
"HeapFree: %8llu kB\n",
total_kb, free_kb, free_kb,
(heap_get_used_bytes() / 1024),
heap_get_total_bytes() / 1024,
heap_get_used_bytes() / 1024,
heap_get_free_bytes() / 1024);
if (offset >= len) return 0;
if (offset + size > (size_t)len) size = len - offset;
memcpy(buffer, text + offset, size);
return (ssize_t)size;
}
static ssize_t proc_cpuinfo_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node;
const cpu_info_t* cpu = cpuid_get_info();
char text[1024];
int len = sprintf(text,
"processor\t: 0\n"
"vendor_id\t: %s\n"
"cpu family\t: %u\n"
"model\t\t: %u\n"
"model name\t: %s\n"
"stepping\t: %u\n"
"flags\t\t: %s%s%s%s%s%s%s%s%s\n"
"bogomips\t: 4800.00\n"
"clflush size\t: 64\n",
cpu->vendor,
cpu->family,
cpu->model_id,
cpu->model,
cpu->stepping,
cpu->has_fpu ? "fpu " : "",
cpu->has_tsc ? "tsc " : "",
cpu->has_pae ? "pae " : "",
cpu->has_apic ? "apic " : "",
cpu->has_sse ? "sse " : "",
cpu->has_sse2 ? "sse2 " : "",
cpu->has_sse3 ? "sse3 " : "",
cpu->has_sse4_1 ? "sse4_1 " : "",
cpu->has_avx ? "avx " : "");
if (offset >= len) return 0;
if (offset + size > (size_t)len) size = len - offset;
memcpy(buffer, text + offset, size);
return (ssize_t)size;
}
static ssize_t proc_net_dev_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
(void)node;
char text[512];
int len = sprintf(text,
"Inter-| Receive | Transmit\n"
" face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n"
" lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
" eth0: %7llu %7llu 0 0 0 0 0 0 %7llu %7llu 0 0 0 0 0 0\n",
e1000_get_rx_bytes(), e1000_get_rx_packets(),
e1000_get_tx_bytes(), e1000_get_tx_packets());
if (offset >= len) return 0;
if (offset + size > (size_t)len) size = len - offset;
memcpy(buffer, text + offset, size);
return (ssize_t)size;
}
void procfs_init(void) {
procfs_root = ramfs_add_dir(NULL, "proc");
vfs_node_t* ver = ramfs_add_file(procfs_root, "version", NULL, 0);
if (ver) { ver->flags = FS_FILE; ver->read = proc_version_read; }
vfs_node_t* uptime = ramfs_add_file(procfs_root, "uptime", NULL, 0);
if (uptime) { uptime->flags = FS_FILE; uptime->read = proc_uptime_read; }
vfs_node_t* mem = ramfs_add_file(procfs_root, "meminfo", NULL, 0);
if (mem) { mem->flags = FS_FILE; mem->read = proc_meminfo_read; }
vfs_node_t* cpu = ramfs_add_file(procfs_root, "cpuinfo", NULL, 0);
if (cpu) { cpu->flags = FS_FILE; cpu->read = proc_cpuinfo_read; }
vfs_node_t* net_dir = ramfs_add_dir(procfs_root, "net");
if (net_dir) {
vfs_node_t* net_dev = ramfs_add_file(net_dir, "dev", NULL, 0);
if (net_dev) { net_dev->flags = FS_FILE; net_dev->read = proc_net_dev_read; }
}
}
vfs_node_t* procfs_get_root(void) {
return procfs_root;
}
+195
View File
@@ -0,0 +1,195 @@
#include <fs/ramfs.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
#define MAX_CHILDREN 32
typedef struct ramfs_entry {
vfs_node_t node;
uint8_t* data;
size_t capacity;
struct ramfs_entry* children[MAX_CHILDREN];
uint32_t child_count;
} ramfs_entry_t;
static vfs_dirent_t shared_dirent;
static int ramfs_mkdir_impl(vfs_node_t* parent, const char* name, mode_t mode);
static int ramfs_create_impl(vfs_node_t* parent, const char* name, mode_t mode);
static struct vfs_dirent* ramfs_readdir(vfs_node_t* node, uint32_t index);
static struct vfs_node* ramfs_finddir(vfs_node_t* node, const char* name);
static ssize_t ramfs_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
ramfs_entry_t* entry = (ramfs_entry_t*)node;
if (!entry || !entry->data || (size_t)offset >= node->length) return 0;
if (offset + size > node->length) {
size = node->length - offset;
}
memcpy(buffer, entry->data + offset, size);
return (ssize_t)size;
}
static ssize_t ramfs_write(vfs_node_t* node, off_t offset, size_t size, const uint8_t* buffer) {
ramfs_entry_t* entry = (ramfs_entry_t*)node;
if (!entry) return -1;
if (offset + size > entry->capacity) {
size_t new_cap = (offset + size + 256) & ~255;
uint8_t* new_data = (uint8_t*)kmalloc(new_cap);
if (!new_data) return -1;
if (entry->data) {
memcpy(new_data, entry->data, node->length);
kfree(entry->data);
}
entry->data = new_data;
entry->capacity = new_cap;
}
memcpy(entry->data + offset, buffer, size);
if (offset + size > node->length) {
node->length = offset + size;
}
return (ssize_t)size;
}
static struct vfs_dirent* ramfs_readdir(vfs_node_t* node, uint32_t index) {
ramfs_entry_t* entry = (ramfs_entry_t*)node;
if (!entry || index >= entry->child_count) return NULL;
strncpy(shared_dirent.name, entry->children[index]->node.name, sizeof(shared_dirent.name) - 1);
shared_dirent.inode = entry->children[index]->node.inode;
shared_dirent.type = entry->children[index]->node.flags;
return &shared_dirent;
}
static struct vfs_node* ramfs_finddir(vfs_node_t* node, const char* name) {
ramfs_entry_t* entry = (ramfs_entry_t*)node;
if (!entry) return NULL;
for (uint32_t i = 0; i < entry->child_count; i++) {
if (strcmp(entry->children[i]->node.name, name) == 0) {
return &entry->children[i]->node;
}
}
return NULL;
}
static int ramfs_mkdir_impl(vfs_node_t* parent, const char* name, mode_t mode) {
ramfs_entry_t* p = (ramfs_entry_t*)parent;
if (!p || p->child_count >= MAX_CHILDREN) return -1;
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
if (!child) return -1;
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
child->node.flags = FS_DIRECTORY;
child->node.mode = mode;
child->node.readdir = ramfs_readdir;
child->node.finddir = ramfs_finddir;
child->node.mkdir = ramfs_mkdir_impl;
child->node.create = ramfs_create_impl;
p->children[p->child_count++] = child;
return 0;
}
static int ramfs_create_impl(vfs_node_t* parent, const char* name, mode_t mode) {
ramfs_entry_t* p = (ramfs_entry_t*)parent;
if (!p || p->child_count >= MAX_CHILDREN) return -1;
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
if (!child) return -1;
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
child->node.flags = FS_FILE;
child->node.mode = mode;
child->node.read = ramfs_read;
child->node.write = ramfs_write;
p->children[p->child_count++] = child;
return 0;
}
vfs_node_t* ramfs_add_file(vfs_node_t* parent, const char* name, const void* content, size_t size) {
ramfs_entry_t* p = (ramfs_entry_t*)parent;
if (!p || p->child_count >= MAX_CHILDREN) return NULL;
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
if (!child) return NULL;
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
child->node.flags = FS_FILE;
child->node.mode = 0644;
child->node.length = size;
child->node.read = ramfs_read;
child->node.write = ramfs_write;
if (size > 0 && content) {
child->capacity = size;
child->data = (uint8_t*)kmalloc(size);
if (child->data) {
memcpy(child->data, content, size);
}
}
p->children[p->child_count++] = child;
return &child->node;
}
vfs_node_t* ramfs_add_dir(vfs_node_t* parent, const char* name) {
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
if (!child) return NULL;
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
child->node.flags = FS_DIRECTORY;
child->node.mode = 0755;
child->node.readdir = ramfs_readdir;
child->node.finddir = ramfs_finddir;
child->node.mkdir = ramfs_mkdir_impl;
child->node.create = ramfs_create_impl;
if (parent) {
ramfs_entry_t* p = (ramfs_entry_t*)parent;
if (p->child_count < MAX_CHILDREN) {
p->children[p->child_count++] = child;
}
}
return &child->node;
}
vfs_node_t* ramfs_create_root(void) {
ramfs_entry_t* root = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
if (!root) return NULL;
strcpy(root->node.name, "/");
root->node.flags = FS_DIRECTORY;
root->node.mode = 0755;
root->node.readdir = ramfs_readdir;
root->node.finddir = ramfs_finddir;
root->node.mkdir = ramfs_mkdir_impl;
root->node.create = ramfs_create_impl;
// Seed default file system structure
vfs_node_t* etc = ramfs_add_dir(&root->node, "etc");
ramfs_add_dir(&root->node, "bin");
ramfs_add_dir(&root->node, "dev");
ramfs_add_dir(&root->node, "proc");
ramfs_add_dir(&root->node, "home");
ramfs_add_dir(&root->node, "tmp");
if (etc) {
ramfs_add_file(etc, "hostname", "sub-os\n", 7);
ramfs_add_file(etc, "os-release", "NAME=\"SUB-OS\"\nVERSION=\"0.2.0-lts\"\nARCH=\"x86_64\"\n", 48);
ramfs_add_file(etc, "resolv.conf", "nameserver 10.0.2.3\nsearch localdomain\n", 39);
ramfs_add_file(etc, "motd", "====================================================\n Welcome to SUB-OS Modular Monolithic Linux Core!\n====================================================\n", 137);
}
const char* readme = "SUB-OS Production-Level Modular Operating System\nArchitecture: x86_64 Long Mode\nSubsystems: PMM, Heap, VFS, PCI, E1000, Net, Crypto, LazyBox\n";
ramfs_add_file(&root->node, "readme.txt", readme, strlen(readme));
return &root->node;
}
+242
View File
@@ -0,0 +1,242 @@
#include <fs/vfs.h>
#include <fs/ramfs.h>
#include <fs/devfs.h>
#include <fs/procfs.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
#include <kernel/printk.h>
#define MAX_OPEN_FILES 64
static vfs_node_t* vfs_root = NULL;
static file_descriptor_t file_descriptors[MAX_OPEN_FILES];
void vfs_init(void) {
memset(file_descriptors, 0, sizeof(file_descriptors));
// 1. Create root RAM filesystem
vfs_root = ramfs_create_root();
// 2. Initialize and mount /dev
devfs_init();
vfs_mount("/dev", devfs_get_root());
// 3. Initialize and mount /proc
procfs_init();
vfs_mount("/proc", procfs_get_root());
printk(KERN_INFO "VFS: Mounted root ramfs, /dev synthetic devfs, and /proc procfs\n");
}
vfs_node_t* vfs_get_root(void) {
return vfs_root;
}
vfs_node_t* vfs_namei(const char* path) {
if (!path || !vfs_root) return NULL;
if (strcmp(path, "/") == 0) return vfs_root;
if (*path == '/') path++; // Skip leading slash
char buffer[256];
strncpy(buffer, path, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
vfs_node_t* current = vfs_root;
char* token = buffer;
while (*token) {
char* next_slash = strchr(token, '/');
if (next_slash) {
*next_slash = '\0';
}
if (current->finddir) {
current = current->finddir(current, token);
if (!current) return NULL;
// Follow mountpoints
if (current->ptr && (current->flags & FS_MOUNTPOINT)) {
current = current->ptr;
}
} else {
return NULL;
}
if (next_slash) {
token = next_slash + 1;
} else {
break;
}
}
return current;
}
int vfs_open(const char* path, uint32_t flags) {
vfs_node_t* node = vfs_namei(path);
if (!node) {
if (flags & O_CREAT) {
// Find parent and create
char parent_path[256];
strncpy(parent_path, path, sizeof(parent_path) - 1);
char* last_slash = strrchr(parent_path, '/');
if (last_slash) {
*last_slash = '\0';
const char* filename = last_slash + 1;
vfs_node_t* parent = vfs_namei(parent_path[0] ? parent_path : "/");
if (parent && parent->create) {
parent->create(parent, filename, 0644);
node = vfs_namei(path);
}
}
}
if (!node) return -1;
}
if (node->open) {
if (node->open(node, flags) != 0) return -1;
}
// Find free file descriptor
for (int fd = 3; fd < MAX_OPEN_FILES; fd++) {
if (!file_descriptors[fd].node) {
file_descriptors[fd].node = node;
file_descriptors[fd].offset = 0;
file_descriptors[fd].flags = flags;
return fd;
}
}
return -1; // Out of file descriptors
}
ssize_t vfs_read(int fd, void* buffer, size_t size) {
if (fd < 0 || fd >= MAX_OPEN_FILES || !file_descriptors[fd].node) return -1;
file_descriptor_t* desc = &file_descriptors[fd];
if (desc->node->read) {
ssize_t bytes_read = desc->node->read(desc->node, desc->offset, size, (uint8_t*)buffer);
if (bytes_read > 0) {
desc->offset += bytes_read;
}
return bytes_read;
}
return -1;
}
ssize_t vfs_write(int fd, const void* buffer, size_t size) {
if (fd < 0 || fd >= MAX_OPEN_FILES || !file_descriptors[fd].node) return -1;
file_descriptor_t* desc = &file_descriptors[fd];
if (desc->node->write) {
ssize_t bytes_written = desc->node->write(desc->node, desc->offset, size, (const uint8_t*)buffer);
if (bytes_written > 0) {
desc->offset += bytes_written;
}
return bytes_written;
}
return -1;
}
off_t vfs_lseek(int fd, off_t offset, int whence) {
if (fd < 0 || fd >= MAX_OPEN_FILES || !file_descriptors[fd].node) return -1;
file_descriptor_t* desc = &file_descriptors[fd];
if (whence == SEEK_SET) desc->offset = offset;
else if (whence == SEEK_CUR) desc->offset += offset;
else if (whence == SEEK_END) desc->offset = desc->node->length + offset;
return desc->offset;
}
int vfs_close(int fd) {
if (fd < 0 || fd >= MAX_OPEN_FILES || !file_descriptors[fd].node) return -1;
if (file_descriptors[fd].node->close) {
file_descriptors[fd].node->close(file_descriptors[fd].node);
}
file_descriptors[fd].node = NULL;
file_descriptors[fd].offset = 0;
return 0;
}
int vfs_mkdir(const char* path, mode_t mode) {
if (!path || !*path) return -1;
char parent_path[256];
strncpy(parent_path, path, sizeof(parent_path) - 1);
parent_path[sizeof(parent_path) - 1] = '\0';
char* last_slash = strrchr(parent_path, '/');
const char* dirname = path;
vfs_node_t* parent = vfs_get_root();
if (last_slash) {
if (last_slash == parent_path) {
parent = vfs_namei("/");
dirname = last_slash + 1;
} else {
*last_slash = '\0';
dirname = last_slash + 1;
parent = vfs_namei(parent_path);
}
}
if (parent && parent->mkdir) {
return parent->mkdir(parent, dirname, mode);
}
return -1;
}
int vfs_create(const char* path, mode_t mode) {
if (!path || !*path) return -1;
char parent_path[256];
strncpy(parent_path, path, sizeof(parent_path) - 1);
parent_path[sizeof(parent_path) - 1] = '\0';
char* last_slash = strrchr(parent_path, '/');
const char* filename = path;
vfs_node_t* parent = vfs_get_root();
if (last_slash) {
if (last_slash == parent_path) {
parent = vfs_namei("/");
filename = last_slash + 1;
} else {
*last_slash = '\0';
filename = last_slash + 1;
parent = vfs_namei(parent_path);
}
}
if (parent && parent->create) {
return parent->create(parent, filename, mode);
}
return -1;
}
int vfs_mount(const char* path, vfs_node_t* fs_root) {
if (!path || !fs_root) return -1;
vfs_node_t* mount_node = vfs_namei(path);
if (!mount_node) {
// Create directory node for mount point
char parent_path[256];
strncpy(parent_path, path, sizeof(parent_path) - 1);
char* last_slash = strrchr(parent_path, '/');
if (last_slash) {
*last_slash = '\0';
const char* dirname = last_slash + 1;
vfs_node_t* parent = vfs_namei(parent_path[0] ? parent_path : "/");
if (parent && parent->mkdir) {
parent->mkdir(parent, dirname, 0755);
mount_node = vfs_namei(path);
}
}
}
if (mount_node) {
mount_node->flags |= FS_MOUNTPOINT;
mount_node->ptr = fs_root;
return 0;
}
return -1;
}