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

+164
View File
@@ -0,0 +1,164 @@
#include <mm/kmalloc.h>
#include <mm/pmm.h>
#include <lib/string.h>
#include <kernel/sync.h>
#include <kernel/printk.h>
#define HEAP_MAGIC 0x53554248 // "SUBH"
#define HEAP_INITIAL_PAGES 1024 // 4 MB initial kernel heap
typedef struct heap_block {
uint32_t magic;
bool is_free;
size_t size; // payload size in bytes
struct heap_block* next;
struct heap_block* prev;
} heap_block_t;
#define BLOCK_HEADER_SIZE sizeof(heap_block_t)
static heap_block_t* heap_start = NULL;
static size_t heap_used_bytes = 0;
static size_t heap_free_bytes = 0;
static size_t heap_total_bytes = 0;
static spinlock_t heap_lock = SPINLOCK_INIT;
void heap_init(void) {
void* initial_mem = pmm_alloc_pages(HEAP_INITIAL_PAGES);
if (!initial_mem) {
printk(KERN_ERR "Heap: Failed to allocate initial %d pages!\n", HEAP_INITIAL_PAGES);
return;
}
heap_start = (heap_block_t*)initial_mem;
heap_total_bytes = HEAP_INITIAL_PAGES * PMM_PAGE_SIZE;
heap_start->magic = HEAP_MAGIC;
heap_start->is_free = true;
heap_start->size = heap_total_bytes - BLOCK_HEADER_SIZE;
heap_start->next = NULL;
heap_start->prev = NULL;
heap_used_bytes = 0;
heap_free_bytes = heap_start->size;
}
void* kmalloc(size_t size) {
if (size == 0) return NULL;
// Align size to 16 bytes for SIMD/64-bit performance
size = (size + 15) & ~15;
spin_lock(&heap_lock);
heap_block_t* curr = heap_start;
while (curr) {
if (curr->magic != HEAP_MAGIC) {
printk(KERN_ERR "Heap Corruption detected at %p!\n", curr);
spin_unlock(&heap_lock);
return NULL;
}
if (curr->is_free && curr->size >= size) {
// Check if block can be split
if (curr->size >= size + BLOCK_HEADER_SIZE + 16) {
heap_block_t* new_block = (heap_block_t*)((uint8_t*)curr + BLOCK_HEADER_SIZE + size);
new_block->magic = HEAP_MAGIC;
new_block->is_free = true;
new_block->size = curr->size - size - BLOCK_HEADER_SIZE;
new_block->next = curr->next;
new_block->prev = curr;
if (curr->next) {
curr->next->prev = new_block;
}
curr->next = new_block;
curr->size = size;
}
curr->is_free = false;
heap_used_bytes += curr->size;
heap_free_bytes -= curr->size;
spin_unlock(&heap_lock);
return (void*)((uint8_t*)curr + BLOCK_HEADER_SIZE);
}
curr = curr->next;
}
spin_unlock(&heap_lock);
printk(KERN_WARNING "Heap: Out of memory for size %llu bytes!\n", size);
return NULL;
}
void* kzalloc(size_t size) {
void* ptr = kmalloc(size);
if (ptr) {
memset(ptr, 0, size);
}
return ptr;
}
void kfree(void* ptr) {
if (!ptr) return;
spin_lock(&heap_lock);
heap_block_t* block = (heap_block_t*)((uint8_t*)ptr - BLOCK_HEADER_SIZE);
if (block->magic != HEAP_MAGIC) {
printk(KERN_ERR "kfree: Invalid pointer / heap corruption %p!\n", ptr);
spin_unlock(&heap_lock);
return;
}
block->is_free = true;
heap_used_bytes -= block->size;
heap_free_bytes += block->size;
// Coalesce with next block if free
if (block->next && block->next->is_free) {
block->size += BLOCK_HEADER_SIZE + block->next->size;
block->next = block->next->next;
if (block->next) {
block->next->prev = block;
}
}
// Coalesce with prev block if free
if (block->prev && block->prev->is_free) {
block->prev->size += BLOCK_HEADER_SIZE + block->size;
block->prev->next = block->next;
if (block->next) {
block->next->prev = block->prev;
}
}
spin_unlock(&heap_lock);
}
void* krealloc(void* ptr, size_t new_size) {
if (!ptr) return kmalloc(new_size);
if (new_size == 0) {
kfree(ptr);
return NULL;
}
heap_block_t* block = (heap_block_t*)((uint8_t*)ptr - BLOCK_HEADER_SIZE);
if (block->magic != HEAP_MAGIC) return NULL;
if (block->size >= new_size) {
return ptr;
}
void* new_ptr = kmalloc(new_size);
if (new_ptr) {
memcpy(new_ptr, ptr, block->size);
kfree(ptr);
}
return new_ptr;
}
size_t heap_get_used_bytes(void) { return heap_used_bytes; }
size_t heap_get_free_bytes(void) { return heap_free_bytes; }
size_t heap_get_total_bytes(void) { return heap_total_bytes; }
+128
View File
@@ -0,0 +1,128 @@
#include <mm/pmm.h>
#include <lib/bitmap.h>
#include <lib/string.h>
#include <kernel/printk.h>
#define MAX_PHYSICAL_PAGES (1024 * 1024) // 4 GB (1,048,576 4KB pages)
#define BITMAP_SIZE (MAX_PHYSICAL_PAGES / 64)
static bitmap_word_t page_bitmap[BITMAP_SIZE];
static uint64_t total_pages = 0;
static uint64_t used_pages = 0;
static uint64_t total_memory_bytes = 0;
static uint64_t usable_memory_bytes = 0;
void pmm_init(void* memory_map, uint64_t memory_map_count) {
// Initially mark all pages as reserved (1 in bitmap)
memset(page_bitmap, 0xFF, sizeof(page_bitmap));
total_pages = 0;
used_pages = 0;
total_memory_bytes = 0;
usable_memory_bytes = 0;
e820_entry_t* entries = (e820_entry_t*)memory_map;
for (uint64_t i = 0; i < memory_map_count; i++) {
uint64_t base = entries[i].base;
uint64_t length = entries[i].length;
uint32_t type = entries[i].type;
total_memory_bytes += length;
if (type == E820_TYPE_USABLE) {
usable_memory_bytes += length;
uint64_t start_page = base / PMM_PAGE_SIZE;
uint64_t page_count = length / PMM_PAGE_SIZE;
for (uint64_t p = 0; p < page_count; p++) {
uint64_t page = start_page + p;
if (page < MAX_PHYSICAL_PAGES) {
bitmap_clear(page_bitmap, page);
if (page >= total_pages) {
total_pages = page + 1;
}
}
}
}
}
// Fallback if no E820 usable regions
if (usable_memory_bytes == 0 || total_pages == 0) {
total_pages = 32768; // 128 MB
total_memory_bytes = 128ULL * 1024 * 1024;
usable_memory_bytes = 128ULL * 1024 * 1024;
for (uint64_t p = 0; p < total_pages; p++) {
bitmap_clear(page_bitmap, p);
}
}
// Reserve lower 4 MB (bootloader, page tables, kernel image)
size_t kernel_reserved_pages = (4 * 1024 * 1024) / PMM_PAGE_SIZE; // 1024 pages
for (size_t p = 0; p < kernel_reserved_pages; p++) {
bitmap_set(page_bitmap, p);
}
// Count actual used pages (bits set in bitmap up to total_pages)
used_pages = 0;
for (uint64_t p = 0; p < total_pages; p++) {
if (bitmap_test(page_bitmap, p)) {
used_pages++;
}
}
printk(KERN_INFO "PMM: Total Memory: %llu MB, Usable: %llu MB, Free Pages: %llu\n",
total_memory_bytes / (1024 * 1024),
usable_memory_bytes / (1024 * 1024),
pmm_get_free_pages());
}
void* pmm_alloc_page(void) {
int64_t page = bitmap_find_first_free(page_bitmap, total_pages);
if (page < 0) {
return NULL; // Out of memory
}
bitmap_set(page_bitmap, (size_t)page);
used_pages++;
return (void*)(page * PMM_PAGE_SIZE);
}
void* pmm_alloc_pages(size_t count) {
if (count == 0) return NULL;
if (count == 1) return pmm_alloc_page();
int64_t start_page = bitmap_find_contiguous_free(page_bitmap, total_pages, count);
if (start_page < 0) return NULL;
for (size_t i = 0; i < count; i++) {
bitmap_set(page_bitmap, (size_t)(start_page + i));
}
used_pages += count;
return (void*)(start_page * PMM_PAGE_SIZE);
}
void pmm_free_page(void* page) {
uint64_t page_idx = (uint64_t)page / PMM_PAGE_SIZE;
if (page_idx < total_pages && bitmap_test(page_bitmap, page_idx)) {
bitmap_clear(page_bitmap, page_idx);
used_pages--;
}
}
void pmm_free_pages(void* page, size_t count) {
uint64_t start_idx = (uint64_t)page / PMM_PAGE_SIZE;
for (size_t i = 0; i < count; i++) {
uint64_t page_idx = start_idx + i;
if (page_idx < total_pages && bitmap_test(page_bitmap, page_idx)) {
bitmap_clear(page_bitmap, page_idx);
used_pages--;
}
}
}
uint64_t pmm_get_total_pages(void) { return total_pages; }
uint64_t pmm_get_used_pages(void) { return used_pages; }
uint64_t pmm_get_free_pages(void) { return (total_pages > used_pages) ? (total_pages - used_pages) : 0; }
uint64_t pmm_get_total_memory(void) { return total_memory_bytes; }
uint64_t pmm_get_usable_memory(void) { return usable_memory_bytes; }