From 43093eaabb996d4e3788460ccfcefcd39c6bb066 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Thu, 11 Sep 2025 12:28:21 +0530 Subject: [PATCH 01/18] README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9e92dcc..7ec8a1c 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ Operating System still under development +This is a lightweight, Machine Learning based Operating System From 725facab6ef6cf494bdc27e9f866ed61ffe61892 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 17 Sep 2025 01:14:32 +0530 Subject: [PATCH 02/18] README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7ec8a1c..4c7c679 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ Operating System still under development This is a lightweight, Machine Learning based Operating System +*Please check the latest update for the kernel update in the branch section* From 5f7714eb445185b0daefdf5a9b2761bb1a0ebf41 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 24 Sep 2025 01:02:12 +0530 Subject: [PATCH 03/18] Add files via upload --- gdt.c | 5 +-- idt.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++----- idt.h | 1 + kernel.c | 13 ++++---- paging.c | 77 ++++++++++++++++++++++++++++++++-------------- pmm.c | 70 +++++++++++++++++++++++++++++++++--------- 6 files changed, 206 insertions(+), 53 deletions(-) diff --git a/gdt.c b/gdt.c index 4cebf5b..89a3afa 100644 --- a/gdt.c +++ b/gdt.c @@ -1,4 +1,5 @@ #include "gdt.h" +#include #define GDT_ENTRIES 5 @@ -20,8 +21,8 @@ void gdt_install(void) { gdt_set_gate(0, 0, 0, 0, 0); // Null segment gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment (Ring 0) gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Kernel data segment (Ring 0) - gdt_set_gate(3, 0, 0x7FFFFFFF, 0xFA, 0xCF); // User code segment (Ring 3, limited) - gdt_set_gate(4, 0, 0x7FFFFFFF, 0xF2, 0xCF); // User data segment (Ring 3, limited) + gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment (Ring 3, limited) + gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User data segment (Ring 3, limited) gdt_flush(); } diff --git a/idt.c b/idt.c index 98a1aa8..3ec18a0 100644 --- a/idt.c +++ b/idt.c @@ -55,20 +55,40 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt[num].flags = flags; } void isr_handler(registers_t *r) { + // Validate register structure pointer + if (r == NULL) { + vga_print_string("Critical error: NULL register pointer in ISR!\n"); + asm volatile("cli"); + for(;;) { asm volatile("hlt"); } + } + vga_print_string("Received interrupt: "); + vga_print_dec(r->int_no); + vga_print_string(" - "); + if (r->int_no < 32) { + // Handle CPU exceptions if (r->int_no < sizeof(exception_messages) / sizeof(exception_messages[0])) { vga_print_string(exception_messages[r->int_no]); } else { vga_print_string("Unknown Exception"); } - vga_print_string("\nEIP: "); + vga_print_string("\nEIP: 0x"); vga_print_hex(r->eip); - vga_print_string(" CS: "); + vga_print_string(" CS: 0x"); vga_print_hex(r->cs); - vga_print_string(" EFLAGS: "); + vga_print_string(" EFLAGS: 0x"); vga_print_hex(r->eflags); - vga_print_string("\nSystem halted!\n"); + vga_print_string(" ESP: 0x"); + vga_print_hex(r->esp); + + // Additional debug information for certain exceptions + if (r->int_no == 13) { // General Protection Fault + vga_print_string("\nError code: 0x"); + vga_print_hex(r->err_code); + } + + vga_print_string("\nSystem halted due to exception!\n"); asm volatile("cli"); for(;;) { asm volatile("hlt"); @@ -91,21 +111,33 @@ void irq_uninstall_handler(int irq) { } void irq_handler(registers_t *r) { + // Validate register structure pointer + if (r == NULL) { + return; + } + + // Validate interrupt number range for IRQs if (r->int_no < 32 || r->int_no > 47) { return; } - + int irq = r->int_no - 32; + + // Double-check IRQ bounds if (irq >= 0 && irq < 16) { void (*handler)(registers_t *r) = irq_routines[irq]; - if (handler) { + if (handler != NULL) { + // Call the registered handler handler(r); } } - + + // Send End of Interrupt signal to PICs if (r->int_no >= 40) { + // Send reset signal to slave PIC outb(0xA0, 0x20); } + // Send reset signal to master PIC outb(0x20, 0x20); } @@ -131,7 +163,7 @@ void idt_install(void) { idt_set_gate(11, (uint32_t)isr11, 0x08, 0x8E); idt_set_gate(12, (uint32_t)isr12, 0x08, 0x8E); idt_set_gate(13, (uint32_t)isr13, 0x08, 0x8E); - idt_set_gate(14, (uint32_t)isr14, 0x08, 0x8E); + idt_set_gate(14, (uint32_t)page_fault_handler, 0x08, 0x8E); idt_set_gate(15, (uint32_t)isr15, 0x08, 0x8E); idt_set_gate(16, (uint32_t)isr16, 0x08, 0x8E); idt_set_gate(17, (uint32_t)isr17, 0x08, 0x8E); @@ -189,4 +221,49 @@ uint32_t inl(uint16_t port) { void outl(uint16_t port, uint32_t val) { asm volatile("outl %0, %1" : : "a"(val), "Nd"(port)); +} +void page_fault_handler(registers_t *r) { + // Function is called when there is a page fault + // The faulting address is stored in the CR2 register + uint32_t faulting_address; + asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); + + // The error code gives us the details about the fault + int present = !(r->err_code & 0x1); // Page is not present + int rw = r->err_code & 0x2; // Write operation? + int us = r->err_code & 0x4; // Were we in user-mode? + int reserved = r->err_code & 0x8; // Overwritten reserved bits? + int id = (r->err_code & 0x10) >> 4; // Instruction fetch (if NX enabled) + int pk = (r->err_code & 0x20) >> 5; // Protection key violation (if PKU enabled) + int ss = (r->err_code & 0x40) >> 6; // Shadow stack violation (Intel CET) + int sgx = (r->err_code & 0x80) >> 7; // SGX access violation (if SGX enabled) + + // Display detailed page fault information + vga_print_string("\n\nPAGE FAULT!\n"); + vga_print_string("Faulting address: 0x"); + vga_print_hex(faulting_address); + vga_print_string("\nError code: 0x"); + vga_print_hex(r->err_code); + vga_print_string("\nEIP: 0x"); + vga_print_hex(r->eip); + + vga_print_string("\nFault type: "); + if (!present) vga_print_string("Page not present "); + if (rw) vga_print_string("Write operation "); + if (us) vga_print_string("User mode "); + if (reserved) vga_print_string("Reserved bits overwritten "); + if (id) vga_print_string("Instruction fetch "); + if (pk) vga_print_string("Protection key violation "); + if (ss) vga_print_string("Shadow stack violation "); + if (sgx) vga_print_string("SGX access violation "); + + vga_print_string("\nSystem halted due to page fault!\n"); + + // Prevent unused variable warnings + (void)id; (void)pk; (void)ss; (void)sgx; + + asm volatile("cli"); + for(;;) { + asm volatile("hlt"); + } } \ No newline at end of file diff --git a/idt.h b/idt.h index b104e19..397f194 100644 --- a/idt.h +++ b/idt.h @@ -28,6 +28,7 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags); void irq_handler(registers_t *r); void isr_handler(registers_t *r); void irq_install_handler(int irq, void (*handler)(registers_t *r)); +void page_fault_handler(registers_t *r); extern void irq0(void); extern void irq1(void); diff --git a/kernel.c b/kernel.c index 6c2ea9f..445af33 100644 --- a/kernel.c +++ b/kernel.c @@ -1,9 +1,11 @@ +#include #include "vga.h" #include "idt.h" #include "gdt.h" #include "keyboard.h" #include "shell.h" #include "timer.h" +#include "paging.h" //#include "pci.h" #include "NIC.h" #include "pmm.h" @@ -15,21 +17,19 @@ void kernel_main(void) { vga_print_string("SimpleOS Kernel v1.0 [SECURED]\n"); vga_print_string("===============================\n\n"); - vga_print_string("Initializing PMM... "); - pmm_init(128*1024*1024); - vga_print_string("[OK]\n"); - vga_print_string("Initializing GDT... "); gdt_install(); vga_print_string("[OK]\n"); - + vga_print_string("Initializing IDT... "); idt_install(); vga_print_string("[OK]\n"); paging_install(); + vga_print_string("Initializing PMM... "); pmm_init(128 * 1024 * 1024); + vga_print_string("[OK]\n"); vga_print_string("Setting up interrupts... "); asm volatile("sti"); @@ -50,7 +50,8 @@ void kernel_main(void) { vga_print_string("Starting shell...\n\n"); shell_init(); - + + // Main kernel loop - wait for interrupts while(1) { asm volatile("hlt"); } diff --git a/paging.c b/paging.c index e7f8111..293d17b 100644 --- a/paging.c +++ b/paging.c @@ -1,29 +1,62 @@ //Identity-map the first 4MB of physical memory +#include #include "paging.h" #include "vga.h" //Static allocation currently, 4MB=4096-byte aligned __attribute__((aligned(4096))) pt_entry_t page_directory[1024]; __attribute__((aligned(4096))) pt_entry_t fpage_table[1024]; -void paging_install(void){ + +void paging_install(void) { vga_print_string("Installing paging... "); - for(int i=0;i<1024;i++){ - fpage_table[i].present=1; - fpage_table[i].user_supervisor=0; - fpage_table[i].pwt=0; - fpage_table[i].pcd=0; - fpage_table[i].accessed=0; - fpage_table[i].reserved=0; - fpage_table[i].rw=1; //Read-write - fpage_table[i].frame=i; -} -//Newly created page goes into the first entry of the page directoy -page_directory[0].frame=(uint32_t)fpage_table>>12; -page_directory[0].present=1; -page_directory[0].rw=1; -asm volatile("mov %0, %%cr3"::"r"(&page_directory)); -uint32_t cr0; -asm volatile("mov %%cr0, %0":"=r"(cr0)); -cr0|=0x80000000; -asm volatile("mov %0, %%cr0"::"r"(cr0)); -vga_print_string("[OK]\n"); -} + + // Verify page directory and table are properly aligned (4KB boundary) + if ((uint32_t)page_directory & 0xFFF) { + vga_print_string("[FAILED - Directory not aligned]\n"); + return; + } + if ((uint32_t)fpage_table & 0xFFF) { + vga_print_string("[FAILED - Table not aligned]\n"); + return; + } + + // Initialize page directory - clear all entries first + for (int i = 0; i < 1024; i++) { + page_directory[i].present = 0; + page_directory[i].rw = 0; + page_directory[i].user_supervisor = 0; + page_directory[i].pwt = 0; + page_directory[i].pcd = 0; + page_directory[i].accessed = 0; + page_directory[i].reserved = 0; + page_directory[i].frame = 0; + } + + // Set up first page table for identity mapping (first 4MB) + for (int i = 0; i < 1024; i++) { + fpage_table[i].present = 1; + fpage_table[i].rw = 1; // Read-write + fpage_table[i].user_supervisor = 0; // Kernel mode + fpage_table[i].pwt = 0; // Write-back caching + fpage_table[i].pcd = 0; // Cacheable + fpage_table[i].accessed = 0; + fpage_table[i].reserved = 0; + fpage_table[i].frame = i; // Identity map: virtual = physical + } + + // Install first page table into page directory + page_directory[0].frame = (uint32_t)fpage_table >> 12; + page_directory[0].present = 1; + page_directory[0].rw = 1; + page_directory[0].user_supervisor = 0; // Kernel mode only + + // Load page directory into CR3 + asm volatile("mov %0, %%cr3" :: "r"(&page_directory) : "memory"); + + // Enable paging by setting bit 31 in CR0 + uint32_t cr0; + asm volatile("mov %%cr0, %0" : "=r"(cr0)); + cr0 |= 0x80000000; // Set PG bit + asm volatile("mov %0, %%cr0" :: "r"(cr0) : "memory"); + + vga_print_string("[OK]\n"); +} \ No newline at end of file diff --git a/pmm.c b/pmm.c index 51a1ade..29751b7 100644 --- a/pmm.c +++ b/pmm.c @@ -18,47 +18,72 @@ typedef struct { static allocation_entry_t allocations[MAX_ALLOCATIONS]; void pmm_init(uint32_t total_memory) { - if (total_memory < KERNEL_START_ADDRESS + (1024 * 1024)) { + // Validate minimum memory requirement + if (total_memory < KERNEL_START_ADDRESS + (2 * 1024 * 1024)) { + // Insufficient memory - system cannot function return; } - - memory_top = KERNEL_START_ADDRESS; - memory_limit = total_memory; + + // Ensure memory alignment to 4KB boundaries + memory_top = (KERNEL_START_ADDRESS + 4095) & ~4095; + memory_limit = total_memory & ~4095; allocation_count = 0; - + + // Initialize allocation table for (int i = 0; i < MAX_ALLOCATIONS; i++) { + allocations[i].address = 0; + allocations[i].size = 0; allocations[i].used = 0; } } void* pmm_alloc(size_t size) { + // Validate input parameters if (size == 0 || size < MIN_ALLOCATION_SIZE || size > MAX_ALLOCATION_SIZE) { return NULL; } - + + // Align size to 16-byte boundary for better performance size = (size + 15) & ~15; - + + // Check if we have space in allocation table if (allocation_count >= MAX_ALLOCATIONS) { return NULL; } - - if (memory_top > memory_limit || (memory_limit - memory_top) < size) { + + // Ensure we don't overflow memory limits with safety margin + if (memory_top >= memory_limit || + (memory_limit - memory_top) < size || + (memory_limit - memory_top) < (4 * 1024)) { // Keep 4KB safety margin return NULL; } - + + // Validate memory_top alignment + if (memory_top & 15) { + memory_top = (memory_top + 15) & ~15; + } + + // Find free allocation slot for (int i = 0; i < MAX_ALLOCATIONS; i++) { if (!allocations[i].used) { allocations[i].address = memory_top; allocations[i].size = size; allocations[i].used = 1; allocation_count++; - + void* ptr = (void*)memory_top; memory_top += size; + + // Clear allocated memory for security + uint8_t* clear_ptr = (uint8_t*)ptr; + for (size_t j = 0; j < size; j++) { + clear_ptr[j] = 0; + } + return ptr; } } - + return NULL; } @@ -66,14 +91,29 @@ void pmm_free(void* ptr) { if (ptr == NULL) { return; } - + uint32_t addr = (uint32_t)ptr; - + + // Validate address is within our memory range + if (addr < KERNEL_START_ADDRESS || addr >= memory_limit) { + return; // Invalid address + } + + // Find and free the allocation for (int i = 0; i < MAX_ALLOCATIONS; i++) { if (allocations[i].used && allocations[i].address == addr) { + // Clear memory before freeing for security + uint8_t* clear_ptr = (uint8_t*)ptr; + for (size_t j = 0; j < allocations[i].size; j++) { + clear_ptr[j] = 0; + } + + // Mark as free + allocations[i].address = 0; + allocations[i].size = 0; allocations[i].used = 0; allocation_count--; - break; + return; } } } From 3659a550f4e895e560e4241c585cac8c41773c68 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Fri, 26 Sep 2025 23:16:51 +0530 Subject: [PATCH 04/18] README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66fae6f..962b447 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -*An Operating System that is light on the system and employs ML based algorithms for its kernel* -*OS STILL UNDER DEVELOPMENT* \ No newline at end of file +*An Operating System that is light on the system and employs ML based algorithms for its kernel. It is an Agentic AI based OS* +*OS STILL UNDER DEVELOPMENT* From 3490e4778020c0c41133f16e217cf5419bfd9144 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:49:03 +0530 Subject: [PATCH 05/18] Kernel-Update-5 The PMM, Timer, and interrupt has been updated and bugs have been fixed --- NIC.C | 7 +- idt.c | 4 +- interrupt.asm | 5 +- kernel.c | 30 +++---- paging.c | 2 +- paging.h | 18 +++- pmm.c | 231 ++++++++++++++++++++++++++++---------------------- pmm.h | 19 +++-- syscall.c | 7 ++ syscall.h | 8 ++ task.c | 72 ++++++++++++++++ task.h | 22 +++++ timer.c | 12 +-- 13 files changed, 291 insertions(+), 146 deletions(-) create mode 100644 syscall.c create mode 100644 syscall.h create mode 100644 task.c create mode 100644 task.h diff --git a/NIC.C b/NIC.C index d66ca70..ed816c2 100644 --- a/NIC.C +++ b/NIC.C @@ -37,7 +37,7 @@ void rtl8139_handler(registers_t *r) { void rtl8139_init(void) { vga_print_string("Initializing RTL8139... "); - // --- Find the card (same as before) --- + // --- Find the card --- uint8_t found = 0; for (uint16_t bus = 0; bus < 256; bus++) { for (uint8_t device = 0; device < 32; device++) { @@ -65,9 +65,8 @@ void rtl8139_init(void) { // 2. Software Reset outb(rtl8139_io_base + REG_COMMAND, 0x10); while((inb(rtl8139_io_base + REG_COMMAND) & 0x10) != 0) { /* wait */ } - - // 3. Allocate Receive Buffer (8K + 16 bytes) - rx_buffer = (uint8_t*)pmm_alloc(8192 + 16); + // 3. Allocate an 16KB block, ie 4 blocks (order 1) for the receive buffer. + rx_buffer = (uint8_t*)pmm_alloc_blocks(4); outl(rtl8139_io_base + REG_RX_BUF, (uint32_t)rx_buffer); // 4. Set Interrupt Mask (Enable Receive OK interrupt) diff --git a/idt.c b/idt.c index 3ec18a0..5a81cb4 100644 --- a/idt.c +++ b/idt.c @@ -1,6 +1,6 @@ #include "idt.h" #include "vga.h" - +#include "syscall.h" static struct idt_entry idt[256]; static struct idt_ptr ip; @@ -209,7 +209,7 @@ void idt_install(void) { idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E); idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E); idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E); - + idt_set_gate(128,(uint32_t)isr128,0x08,0xEE); asm volatile("lidt %0" : : "m"(ip)); asm volatile("sti"); } diff --git a/interrupt.asm b/interrupt.asm index 83d50bf..cd5de50 100644 --- a/interrupt.asm +++ b/interrupt.asm @@ -48,7 +48,7 @@ global irq12 global irq13 global irq14 global irq15 - +global isr128 extern isr_handler extern irq_handler @@ -107,7 +107,7 @@ isr_no_error 28 isr_no_error 29 isr_no_error 30 isr_no_error 31 - +isr_no_error 128 irq_stub 0, 32 irq_stub 1, 33 irq_stub 2, 34 @@ -170,5 +170,4 @@ irq_common_stub: popa add esp, 8 - sti iret \ No newline at end of file diff --git a/kernel.c b/kernel.c index 445af33..cfb7697 100644 --- a/kernel.c +++ b/kernel.c @@ -9,39 +9,33 @@ //#include "pci.h" #include "NIC.h" #include "pmm.h" - +#include "task.h" +#include "syscall.h" +void counter_task(){ + int i=0; + while(1){ + vga_putentryat('A' + (i++%26),0x0F,79,0); + } +} void kernel_main(void) { vga_init(); vga_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK)); vga_print_string("SimpleOS Kernel v1.0 [SECURED]\n"); vga_print_string("===============================\n\n"); - - vga_print_string("Initializing GDT... "); gdt_install(); - vga_print_string("[OK]\n"); - - vga_print_string("Initializing IDT... "); idt_install(); - vga_print_string("[OK]\n"); - + syscalls_install(); paging_install(); - - vga_print_string("Initializing PMM... "); pmm_init(128 * 1024 * 1024); - vga_print_string("[OK]\n"); - - vga_print_string("Setting up interrupts... "); asm volatile("sti"); - vga_print_string("[OK]\n"); - keyboard_install(); timer_install(); - //pci_scan(); rtl8139_init(); - + tasking_install(); + create_task("shell",shell_init); + create_task("counter",counter_task); uint32_t free_mem = pmm_get_free_memory(); - vga_print_string("Free memory: "); vga_print_dec(free_mem / 1024); vga_print_string(" KB\n"); diff --git a/paging.c b/paging.c index 293d17b..c674b56 100644 --- a/paging.c +++ b/paging.c @@ -1,4 +1,4 @@ -//Identity-map the first 4MB of physical memory +ed//Identity-map the first 4MB of physical memory #include #include "paging.h" #include "vga.h" diff --git a/paging.h b/paging.h index 0e12110..3c84d11 100644 --- a/paging.h +++ b/paging.h @@ -2,15 +2,27 @@ #define PAGING_H #include #include "idt.h" //This is for interrupt handling + +// Paging memory layout constants +#define PAGING_STRUCTURES_START ((uint32_t)&page_directory) +#define PAGING_STRUCTURES_SIZE (8192) // 8KB for directory + table +extern pt_entry_t page_directory[1024]; +extern pt_entry_t fpage_table[1024]; //Below is for defining page table entry typedef struct pt_entry{ uint32_t present:1; uint32_t rw:1; - uint32_t us:1; + uint32_t user_supervisor:1; + uint32_t pwt:1; // Page Write-Through + uint32_t pcd:1; // Page Cache Disable uint32_t accessed:1; uint32_t dirty:1; - uint32_t unused:7;// Amalgamation of unused and reserved bits - uint32_t frame:20; //Frame address + uint32_t reserved:5; // Reserved bits + uint32_t frame:20; // Frame address } pt_entry_t; + +// Function declarations void paging_install(void); +uint32_t paging_get_reserved_start(void); +uint32_t paging_get_reserved_end(void); #endif diff --git a/pmm.c b/pmm.c index 29751b7..4596312 100644 --- a/pmm.c +++ b/pmm.c @@ -1,126 +1,155 @@ -#include "pmm.h" #include +#include -static uint32_t memory_top; -static uint32_t memory_limit; -static uint32_t allocation_count = 0; -#define KERNEL_START_ADDRESS 0x200000 -#define MAX_ALLOCATIONS 1024 -#define MIN_ALLOCATION_SIZE 16 -#define MAX_ALLOCATION_SIZE (1024 * 1024) - -typedef struct { - uint32_t address; - uint32_t size; - int used; -} allocation_entry_t; - -static allocation_entry_t allocations[MAX_ALLOCATIONS]; - -void pmm_init(uint32_t total_memory) { - // Validate minimum memory requirement - if (total_memory < KERNEL_START_ADDRESS + (2 * 1024 * 1024)) { - // Insufficient memory - system cannot function - return; - } +#define PAGE_SIZE 4096 +#define MAX_ORDER 10 // 4KB * 2^10 = 4MB +#define KERNEL_RESERVED_END 0x200000U // bytes (2MB) - // Ensure memory alignment to 4KB boundaries - memory_top = (KERNEL_START_ADDRESS + 4095) & ~4095; - memory_limit = total_memory & ~4095; - allocation_count = 0; +typedef enum { PAGE_STATE_FREE=0, PAGE_STATE_USED=1, PAGE_STATE_RESERVED=2 } page_state_t; - // Initialize allocation table - for (int i = 0; i < MAX_ALLOCATIONS; i++) { - allocations[i].address = 0; - allocations[i].size = 0; - allocations[i].used = 0; - } -} +typedef struct page_frame { + struct page_frame* next; + struct page_frame* prev; + uint8_t order; + page_state_t state; + // ... other metadata +} page_frame_t; -void* pmm_alloc(size_t size) { - // Validate input parameters - if (size == 0 || size < MIN_ALLOCATION_SIZE || size > MAX_ALLOCATION_SIZE) { - return NULL; - } +static page_frame_t* page_frame_database = NULL; +static page_frame_t* free_lists[MAX_ORDER + 1]; +static uint32_t total_pages = 0; - // Align size to 16-byte boundary for better performance - size = (size + 15) & ~15; +static inline uint32_t idx_from_addr(void* addr) { + return (uint32_t)((uintptr_t)addr / PAGE_SIZE); +} +static inline void* addr_from_idx(uint32_t idx) { + return (void*)((uintptr_t)idx * PAGE_SIZE); +} +static inline uint32_t get_buddy_index(uint32_t index, uint32_t order) { + return index ^ (1u << order); +} - // Check if we have space in allocation table - if (allocation_count >= MAX_ALLOCATIONS) { - return NULL; - } +void pmm_init(uint32_t memory_end_bytes) { + total_pages = memory_end_bytes / PAGE_SIZE; + size_t db_size = total_pages * sizeof(page_frame_t); + uint32_t db_pages = (db_size + PAGE_SIZE - 1) / PAGE_SIZE; - // Ensure we don't overflow memory limits with safety margin - if (memory_top >= memory_limit || - (memory_limit - memory_top) < size || - (memory_limit - memory_top) < (4 * 1024)) { // Keep 4KB safety margin - return NULL; + uint32_t reserved_pages = (KERNEL_RESERVED_END / PAGE_SIZE) + db_pages; + if (reserved_pages >= total_pages) { + return; } - - // Validate memory_top alignment - if (memory_top & 15) { - memory_top = (memory_top + 15) & ~15; + page_frame_database = (page_frame_t*)(uintptr_t)KERNEL_RESERVED_END; + uint32_t usable_start = reserved_pages; + uint32_t usable_pages = total_pages - reserved_pages; + for (uint32_t i = 0; i < total_pages; ++i) { + page_frame_database[i].state = PAGE_STATE_FREE; + page_frame_database[i].order = 0; + page_frame_database[i].next = NULL; + page_frame_database[i].prev = NULL; } - - // Find free allocation slot - for (int i = 0; i < MAX_ALLOCATIONS; i++) { - if (!allocations[i].used) { - allocations[i].address = memory_top; - allocations[i].size = size; - allocations[i].used = 1; - allocation_count++; - - void* ptr = (void*)memory_top; - memory_top += size; - - // Clear allocated memory for security - uint8_t* clear_ptr = (uint8_t*)ptr; - for (size_t j = 0; j < size; j++) { - clear_ptr[j] = 0; - } - - return ptr; + for (uint32_t i = 0; i < reserved_pages; ++i) { + page_frame_database[i].state = PAGE_STATE_RESERVED; + } + for (int i = 0; i <= MAX_ORDER; ++i) free_lists[i] = NULL; + uint32_t current = usable_start; + while (current < total_pages) { + int order = MAX_ORDER; + while (order >= 0) { + uint32_t block_size = 1u << order; + if ((current % block_size) == 0 && (current + block_size) <= total_pages) break; + --order; } + if (order < 0) { // fallback to single page + order = 0; + } + page_frame_t* f = &page_frame_database[current]; + f->order = (uint8_t)order; + f->state = PAGE_STATE_FREE; + // push to free list head + f->prev = NULL; + f->next = free_lists[order]; + if (free_lists[order]) free_lists[order]->prev = f; + free_lists[order] = f; + + current += (1u << order); } +} +void* pmm_alloc_page(void) { + for (int order = 0; order <= MAX_ORDER; ++order) { + if (!free_lists[order]) continue; + page_frame_t* block = free_lists[order]; + free_lists[order] = block->next; + if (free_lists[order]) free_lists[order]->prev = NULL; + int cur_order = order; + uint32_t base_idx = (uint32_t)(block - page_frame_database); + while (cur_order > 0) { + cur_order--; + uint32_t buddy_idx = base_idx + (1u << cur_order); + page_frame_t* buddy = &page_frame_database[buddy_idx]; + buddy->order = (uint8_t)cur_order; + buddy->state = PAGE_STATE_FREE; + buddy->next = free_lists[cur_order]; + if (free_lists[cur_order]) free_lists[cur_order]->prev = buddy; + buddy->prev = NULL; + free_lists[cur_order] = buddy; + } + + block->order = 0; + block->state = PAGE_STATE_USED; + block->next = block->prev = NULL; + uint32_t idx = (uint32_t)(block - page_frame_database); + return addr_from_idx(idx); + } return NULL; } -void pmm_free(void* ptr) { - if (ptr == NULL) { - return; - } +void pmm_free_page(void* p) { + if (!p) return; + uintptr_t addr = (uintptr_t)p; + if (addr % PAGE_SIZE) return; - uint32_t addr = (uint32_t)ptr; + uint32_t idx = (uint32_t)(addr / PAGE_SIZE); + if (idx >= total_pages) return; - // Validate address is within our memory range - if (addr < KERNEL_START_ADDRESS || addr >= memory_limit) { - return; // Invalid address - } + page_frame_t* frame = &page_frame_database[idx]; + if (frame->state == PAGE_STATE_RESERVED) return; + + frame->state = PAGE_STATE_FREE; + frame->order = 0; - // Find and free the allocation - for (int i = 0; i < MAX_ALLOCATIONS; i++) { - if (allocations[i].used && allocations[i].address == addr) { - // Clear memory before freeing for security - uint8_t* clear_ptr = (uint8_t*)ptr; - for (size_t j = 0; j < allocations[i].size; j++) { - clear_ptr[j] = 0; - } - - // Mark as free - allocations[i].address = 0; - allocations[i].size = 0; - allocations[i].used = 0; - allocation_count--; - return; + for (int order = 0; order < MAX_ORDER; ++order) { + uint32_t buddy_idx = get_buddy_index(idx, order); + if (buddy_idx >= total_pages) break; + page_frame_t* buddy = &page_frame_database[buddy_idx]; + + if (buddy->state != PAGE_STATE_FREE || buddy->order != order) { + break; // can't merge } + if (buddy->prev) buddy->prev->next = buddy->next; + else free_lists[order] = buddy->next; + if (buddy->next) buddy->next->prev = buddy->prev; + if (buddy_idx < idx) idx = buddy_idx; + frame = &page_frame_database[idx]; + frame->order = (uint8_t)(order + 1); + frame->state = PAGE_STATE_FREE; } + int final_order = frame->order; + frame->next = free_lists[final_order]; + if (free_lists[final_order]) free_lists[final_order]->prev = frame; + frame->prev = NULL; + free_lists[final_order] = frame; } uint32_t pmm_get_free_memory(void) { - if (memory_limit > memory_top) { - return memory_limit - memory_top; + uint32_t total_free = 0; + for (int order = 0; order <= MAX_ORDER; ++order) { + uint32_t block_pages = (1u << order); + page_frame_t* cur = free_lists[order]; + while (cur) { + total_free += block_pages * PAGE_SIZE; + cur = cur->next; + } } - return 0; -} \ No newline at end of file + return total_free; +} diff --git a/pmm.h b/pmm.h index 5b9885f..1c88f91 100644 --- a/pmm.h +++ b/pmm.h @@ -1,12 +1,19 @@ #ifndef PMM_H #define PMM_H - #include -#include +#define PAGE_STATE_FREE 0x01 +#define PAGE_STATE_USED 0x02 +#define PAGE_STATE_RESERVED 0x04 +#define PAGE_STATE_KERNEL 0x08 +typedef struct page_frame { + uint8_t state; + uint8_t order; + struct page_frame* next; + struct page_frame* prev; -void pmm_init(uint32_t memory_size); -void* pmm_alloc(size_t size); -void pmm_free(void* ptr); +} page_frame_t; +void pmm_init(uint32_t memory_end); +void* pmm_alloc_page(void); +void pmm_free_page(void* p); uint32_t pmm_get_free_memory(void); - #endif \ No newline at end of file diff --git a/syscall.c b/syscall.c new file mode 100644 index 0000000..b1cc7df --- /dev/null +++ b/syscall.c @@ -0,0 +1,7 @@ +#include "syscall.h" +#include "vga.h" +void syscall_handler(registers_t *r){ + if (r->eax==0){ + vga_print_string("SYSTEM CALL RECEIVED!, SIMPLE OS WORKING\n"); + } +} \ No newline at end of file diff --git a/syscall.h b/syscall.h new file mode 100644 index 0000000..c1bb157 --- /dev/null +++ b/syscall.h @@ -0,0 +1,8 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +#include "idt.h" + +void syscalls_install(void); + +#endif \ No newline at end of file diff --git a/task.c b/task.c new file mode 100644 index 0000000..9931fcc --- /dev/null +++ b/task.c @@ -0,0 +1,72 @@ +#include "task.h" +#include "pmm.h" +#include "vga.h" +#include "timer.h" +#include "idt.h" +#include +static task_t* current_task; +static task_t* ready_queue; +static int next_pid = 1; +void tasking_install(void) { + vga_print_string("Initializing multitasking... "); + current_task = (task_t*)pmm_alloc_page(); + memset(current_task, 0, sizeof(task_t)); + current_task->id = next_pid++; + current_task->state = TASK_RUNNING; + current_task->kernel_stack = NULL; + current_task->next = NULL; + ready_queue = current_task; + + vga_print_string("[OK]\n"); +} +void create_task(char* name, void (*entry_point)(void)) { + (void)name; // Name is for debugging, unused for now + asm volatile("cli"); + task_t* new_task = (task_t*)pmm_alloc_page(); + memset(new_task, 0, sizeof(task_t)); + + new_task->id = next_pid++; + new_task->state = TASK_READY; + // Allocate one physical page for the kernel stack. + // pmm_alloc_page() returns the base (lowest address) of the page. + // Since the x86 stack grows downward, set the initial stack pointer + // to the *top* of the page by adding PAGE_SIZE. + // Use explicit cast to avoid pointer arithmetic surprises. + new_task->kernel_stack = (uint32_t)pmm_alloc_page() + PAGE_SIZE; + uint32_t stack_top = (uint32_t)new_task->kernel_stack; + registers_t* initial_regs = (registers_t*)(stack_top - sizeof(registers_t)); + memset(initial_regs, 0, sizeof(registers_t)); + initial_regs->eax = 0; + initial_regs->ebx = 0; + initial_regs->ecx = 0; + initial_regs->edx = 0; + initial_regs->esi = 0; + initial_regs->edi = 0; + initial_regs->ebp = 0; + initial_regs->eip = (uint32_t)entry_point; + initial_regs->cs = 0x08; + initial_regs->eflags = 0x202; + new_task->regs.esp = (uint32_t)initial_regs; + new_task->next = NULL; + task_t* temp = ready_queue; + while(temp->next) { + temp = temp->next; + } + temp->next = new_task; + asm volatile("sti"); +} + +void schedule(registers_t* r) { + if (!current_task) return; + current_task->regs = *r; + if (!current_task->next) { + return; + } + task_t* prev_task = current_task; + current_task = current_task->next; + if (!current_task) { + current_task = ready_queue; + } + current_task->state = TASK_RUNNING; + *r = current_task->regs; +} \ No newline at end of file diff --git a/task.h b/task.h new file mode 100644 index 0000000..a6f73b6 --- /dev/null +++ b/task.h @@ -0,0 +1,22 @@ +#ifndef TASK_H +#define TASK_H +#include +#include "idt.h" +typedef enum { + TASK_RUNNING, + TASK_READY, + TASK_SLEEPING, + TASK_DEAD +} task_state_t; +typedef struct task { + int id; + registers_t regs; + void* kernel_stack; + task_state_t state; + struct task* next; +} task_t; +void tasking_install(void); +void create_task(char* name, void (*entry_point)(void)); +void schedule(registers_t* r); + +#endif \ No newline at end of file diff --git a/timer.c b/timer.c index 5492af1..ef36c2b 100644 --- a/timer.c +++ b/timer.c @@ -1,24 +1,20 @@ #include "timer.h" -#include "idt.h" -#include "vga.h" +#include "task.h" volatile uint32_t ticks = 0; void timer_handler(registers_t *r) { - (void)r; ticks++; + schedule(r); } uint32_t get_ticks() { return ticks; } void timer_install() { - vga_print_string("Installing timer... "); - int frequency = 500; + int frequency = 100; uint32_t divisor = 1193180 / frequency; outb(0x43, 0x36); uint8_t l = (uint8_t)(divisor & 0xFF); uint8_t h = (uint8_t)((divisor >> 8) & 0xFF); outb(0x40, l); outb(0x40, h); - irq_install_handler(0, timer_handler); - - vga_print_string("[OK]\n"); + irq_install_handler(0, timer_handler); } \ No newline at end of file From 5d697f34173193f0c7be07347452386596fa5192 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:17:20 +0530 Subject: [PATCH 06/18] README.md --- README.md | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 962b447..b5820b3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,198 @@ -*An Operating System that is light on the system and employs ML based algorithms for its kernel. It is an Agentic AI based OS* -*OS STILL UNDER DEVELOPMENT* +# SimpleOS - A Lightweight x86 Operating System + +SimpleOS is a lightweight, robust operating system for the x86 architecture, written in C and Assembly. It provides a foundational set of OS features, including protected mode, memory segmentation, and a full interrupt handling system, making it ideal for embedded applications, legacy system revival, or as a base for custom OS development. + +## Features + +- **Bootloader**: Custom 16-bit bootloader that transitions to protected mode +- **GDT (Global Descriptor Table)**: Memory segmentation with kernel/user segments +- **IDT (Interrupt Descriptor Table)**: Complete interrupt handling system with exception messages +- **VGA Text Driver**: Full-featured text output with scrolling, colors, and formatting +- **Keyboard Driver**: PS/2 keyboard support with scan code translation +- **Interactive Shell**: Command-line interface with built-in commands +- **Memory Management**: Basic protected mode memory setup +- **Interrupt Handling**: Proper CPU exception and hardware interrupt handling + +## Architecture + +### Boot Process +1. **Real Mode Boot**: 16-bit bootloader loads from sector 0 +2. **A20 Line**: Enable extended memory access +3. **Protected Mode**: Switch to 32-bit protected mode +4. **Kernel Entry**: Jump to kernel main function + +### Kernel Components + +#### VGA Driver (`vga.c`, `vga.h`) +- Text mode output at 0xB8000 +- 80x25 character display +- 16-color palette support +- Automatic scrolling +- Hex/decimal number formatting + +#### GDT Manager (`gdt.c`, `gdt.h`) +- 5-entry descriptor table (null, kernel code/data, user code/data) +- Proper segment reloading +- 4GB flat memory model + +#### IDT Manager (`idt.c`, `idt.h`) +- 256 interrupt descriptors +- Exception handlers with descriptive messages +- Hardware interrupt support (PIC reprogramming) +- Assembly interrupt stubs (`interrupt.asm`) + +#### Keyboard Driver (`keyboard.c`, `keyboard.h`) +- PS/2 keyboard interrupt handler (IRQ1) +- Scan code to ASCII translation +- Shift and Caps Lock support +- Key buffer for input queuing +- Integration with shell interface + +#### Interactive Shell (`shell.c`, `shell.h`) +- Command-line interface +- Built-in commands: help, clear, about, reboot, halt +- Command history and input processing +- Backspace support and line editing + +#### Kernel Main (`kernel.c`) +- System initialization sequence +- Colorized boot messages +- Shell initialization and main loop + +## Building + +### Prerequisites + +You need a cross-compilation toolchain for i686-elf: +- `i686-elf-gcc` (C compiler) +- `i686-elf-ld` (Linker) +- `nasm` (Netwide Assembler) + +### Installation on Ubuntu/Debian: +```bash +sudo apt-get install build-essential nasm qemu-system-x86 +# For the cross-compiler, you can build it from source. +# A good guide can be found here: https://wiki.osdev.org/GCC_Cross-Compiler +# Alternatively, some package managers might have pre-built toolchains. +``` + +### Installation on Windows: +1. Install MSYS2 +2. Install cross-compilation tools: +```bash +pacman -S mingw-w64-i686-gcc nasm +``` + +### Compilation +```bash +make all # Build OS image +make clean # Remove build files +make qemu # Run with QEMU (if installed) +make bochs # Run with Bochs (if installed) +make help # Show available targets +``` + +## Running + +### QEMU (Recommended) +```bash +qemu-system-i386 -fda build/os.img +``` + +### Bochs +```bash +bochs -f bochsrc.txt +``` + +### VirtualBox/VMware +1. Create new VM with floppy disk +2. Mount `build/os.img` as floppy image +3. Boot from floppy + +## Using the Shell + +Once the system boots, you'll see the SimpleOS shell prompt: + +``` +SimpleOS> +``` + +Available commands: +- `help` - Display available commands +- `clear` - Clear the screen +- `about` - Show system information +- `reboot` - Reboot the system +- `halt` - Halt the system + +The shell supports: +- Basic command input with Enter to execute +- Backspace for editing +- Automatic scrolling when screen is full + +## File Structure + +``` +SimpleOS/ +├── boot/ +│ └── boot.asm # 16-bit bootloader +├── kernel/ +│ ├── kernel.c # Kernel main and initialization +│ ├── gdt.c/.h # Global Descriptor Table +│ ├── idt.c/.h # Interrupt Descriptor Table +│ ├── vga.c/.h # VGA text driver +│ ├── keyboard.c/.h # PS/2 keyboard driver +│ ├── shell.c/.h # Interactive command shell +│ └── interrupt.asm # Assembly interrupt handlers +├── build/ # Build output (auto-generated) +├── Makefile # Build configuration +├── linker.ld # Linker script +└── README.md # This file +``` + +## Technical Details + +### Memory Layout +- **0x00007C00**: Bootloader load address +- **0x00100000**: Kernel load address (1MB) +- **0x000B8000**: VGA text buffer +- **0x00090000**: Stack pointer + +### Interrupts +- **ISR 0-31**: CPU exceptions (division error, page fault, etc.) +- **IRQ 0-15**: Hardware interrupts (timer, keyboard, etc.) +- **PIC Remapping**: Master PIC (0x20-0x27), Slave PIC (0x28-0x2F) + +### Color Codes (VGA) +- 0=Black, 1=Blue, 2=Green, 3=Cyan, 4=Red, 5=Magenta +- 6=Brown, 7=Light Grey, 8=Dark Grey, 9=Light Blue +- 10=Light Green, 11=Light Cyan, 12=Light Red +- 13=Light Magenta, 14=Light Brown, 15=White + +## Roadmap + +Future development is focused on expanding the kernel's capabilities. Key areas on our roadmap include: + +- **System Call Interface**: A formal system call API for user-kernel interaction. +- **Advanced Drivers**: Support for timers (IRQ0) and other hardware. +- **Dynamic Memory Management**: A robust heap allocator (`malloc`/`free`). +- **Process and Task Management**: Implementation of multitasking and scheduling. + +### Debugging +- Use QEMU with GDB: `qemu-system-i386 -s -S -fda build/os.img` +- Connect GDB: `gdb -ex "target remote :1234"` +- Enable QEMU monitor: Add `-monitor stdio` + +## Contributing + +SimpleOS is an open-source product and we welcome contributions from the community. If you are interested in contributing, please feel free to fork the repository, make your changes, and submit a pull request. We are actively looking for improvements in drivers, memory management, and performance optimizations. + +## License + +This product is released under the Apache 2.0 License. See the LICENSE file for details. + +## References + +- [OSDev Wiki](https://wiki.osdev.org/) - Comprehensive OS development resource +- [Intel 80386 Manual](https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html) +- [Bran's Kernel Development Tutorial](http://www.osdever.net/bkerndev/Docs/title.htm) +- [JamesM's Kernel Development Tutorials](https://web.archive.org/web/20160412174753/http://www.jamesmolloy.co.uk/tutorial_html/index.html) From d1699571c6bf250f29542f2b967c2b49ab7c71a3 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:20:28 +0530 Subject: [PATCH 07/18] README.md --- README.md | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b5820b3..29ef9cf 100644 --- a/README.md +++ b/README.md @@ -117,17 +117,13 @@ Once the system boots, you'll see the SimpleOS shell prompt: SimpleOS> ``` -Available commands: -- `help` - Display available commands -- `clear` - Clear the screen -- `about` - Show system information -- `reboot` - Reboot the system -- `halt` - Halt the system - -The shell supports: -- Basic command input with Enter to execute -- Backspace for editing -- Automatic scrolling when screen is full +The agent will process your request and respond accordingly. + +### Example Interactions +- `> what time is it?` +- `> create a new file named notes.txt` +- `> tell me about the CPU` +- `> reboot the machine in 5 minutes` ## File Structure @@ -141,7 +137,7 @@ SimpleOS/ │ ├── idt.c/.h # Interrupt Descriptor Table │ ├── vga.c/.h # VGA text driver │ ├── keyboard.c/.h # PS/2 keyboard driver -│ ├── shell.c/.h # Interactive command shell +│ ├── agent.c/.h # The core AI agent logic │ └── interrupt.asm # Assembly interrupt handlers ├── build/ # Build output (auto-generated) ├── Makefile # Build configuration @@ -172,13 +168,11 @@ SimpleOS/ Future development is focused on expanding the kernel's capabilities. Key areas on our roadmap include: -- **System Call Interface**: A formal system call API for user-kernel interaction. -- **Advanced Drivers**: Support for timers (IRQ0) and other hardware. -- **Dynamic Memory Management**: A robust heap allocator (`malloc`/`free`). -- **Process and Task Management**: Implementation of multitasking and scheduling. +- **Agent Tooling**: Expanding the set of kernel functions (tools) the LLM agent can use. +- **Long-Term Memory**: Implementing a file system to give the agent persistent memory. +- **Multitasking**: Allowing the agent to manage and execute multiple background processes. ### Debugging -- Use QEMU with GDB: `qemu-system-i386 -s -S -fda build/os.img` - Connect GDB: `gdb -ex "target remote :1234"` - Enable QEMU monitor: Add `-monitor stdio` @@ -188,7 +182,7 @@ SimpleOS is an open-source product and we welcome contributions from the communi ## License -This product is released under the Apache 2.0 License. See the LICENSE file for details. +This product is released under the MIT License. See the LICENSE file for details. ## References From 872b8df3e0999273c7c98be3b7cd017db76520fd Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Sun, 12 Oct 2025 00:11:02 +0530 Subject: [PATCH 08/18] Add files via upload --- mutex.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mutex.h | 16 ++++++++++++++ spinlock.c | 34 ++++++++++++++++++++++++++++ spinlock.h | 9 ++++++++ task.c | 58 ++++++++++++++++++++++++++++++++++++++---------- task.h | 9 ++++++-- 6 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 mutex.c create mode 100644 mutex.h create mode 100644 spinlock.c create mode 100644 spinlock.h diff --git a/mutex.c b/mutex.c new file mode 100644 index 0000000..711ba70 --- /dev/null +++ b/mutex.c @@ -0,0 +1,65 @@ +#include "mutex.h" +#include "idt.h" +#include "vga.h" +#include "spinlock.h" +extern void schedule(void);//Generic scheduler call +extern task_t* get_current_task(void);//Function to get the current task +void mutex_init(mutex_t* mutex){ + spinlock_init(&mutex->lock);//Initializing the guard + mutex->locked = false; + mutex->owner = NULL; + mutex->wait_queue = NULL; +} +void mutex_lock(mutex_t* mutex){ + unsigned long flags=spinlock_acquire_irqsave(&mutex->lock);//Acquire the guard + task_t* current=get_current_task();//Get the current task + + while (mutex->locked) { + // The mutex is locked, so we need to wait. + current->state = TASK_BLOCKED; + + // Add current task to the end of the wait queue + current->next = NULL; + if (mutex->wait_queue == NULL) { + mutex->wait_queue = current; + } else { + task_t* temp = mutex->wait_queue; + while (temp->next != NULL) { + temp = temp->next; + } + temp->next = current; + } + + // Release the spinlock and schedule another task. + // This must be atomic. + schedule_and_release_lock(&mutex->lock, flags); + + // When we wake up, re-acquire the spinlock to re-check the mutex state. + flags = spinlock_acquire_irqsave(&mutex->lock); + } + + mutex->locked=true; + mutex->owner=current; + spinlock_release_irqrestore(&mutex->lock, flags); +} + +void mutex_unlock(mutex_t* mutex){ + unsigned long flags=spinlock_acquire_irqsave(&mutex->lock); + if (mutex->owner!=get_current_task()){ + // Error: current task does not own the mutex + spinlock_release_irqrestore(&mutex->lock,flags); + return; + } + task_t* next_task=mutex->wait_queue;//dequeue the next waiting task + if (next_task!=NULL){ + mutex->wait_queue=next_task->next; + mutex->locked = true; // The lock remains held, just transferred + mutex->owner=next_task; + next_task->state=TASK_READY; + } + else{ + mutex->locked=false; + mutex->owner=NULL; + } + spinlock_release_irqrestore(&mutex->lock,flags); +} diff --git a/mutex.h b/mutex.h new file mode 100644 index 0000000..f49257a --- /dev/null +++ b/mutex.h @@ -0,0 +1,16 @@ +#ifndef MUTEX_H +#define MUTEX_H +#include "task.h" +#include "spinlock.h" +#include +typedef struct mutex { + spinlock_t lock; // Spinlock in order to ensure that the atomic operations on the mutex itself are thread-safe + bool locked;// This is for checking if the mutex is currrently being held or not + task_t* owner;//The task that currently holds the lock + task_t* wait_queue;//A linked list of tasks waiting for the lock. +} mutex_t; +//Function prototypes for the mutexes operations we would be defining +void mutex_init(mutex_t* mutex); +void mutex_lock(mutex_t* mutex); +void mutex_unlock(mutex_t* mutex); +#endif//MUTEX_H \ No newline at end of file diff --git a/spinlock.c b/spinlock.c new file mode 100644 index 0000000..4336825 --- /dev/null +++ b/spinlock.c @@ -0,0 +1,34 @@ +#include "spinlock.h" +void spinlock_init(spinlock_t* lock) { + *lock = 0; // Initialize the lock to unlocked state +} +unsigned long spinlock_acquire_irqsave(spinlock_t* lock) { + unsigned long flags; + asm volatile( + "pushf\n" // Save EFLAGS to stack + "pop %0\n" // Pop into flags variable + "cli\n" // Disable interrupts + : "=r"(flags) // Output operand + : // No input operands + : "memory" // Clobber memory to prevent reordering + ); + + while (__atomic_test_and_set(lock, __ATOMIC_ACQUIRE)) { + // Spin-wait (busy wait) + while (*lock) { + asm volatile("pause"); // Hint to CPU for better power management + } + } + return flags; +} +void spinlock_release_irqrestore(spinlock_t* lock, unsigned long flags) { + __atomic_clear(lock, __ATOMIC_RELEASE); // Release the lock + + asm volatile( + "push %0\n" // Push saved flags onto stack + "popf\n" // Restore EFLAGS from stack + : // No output operands + : "r"(flags) // Input operand + : "memory" // Clobber memory to prevent reordering + ); +} \ No newline at end of file diff --git a/spinlock.h b/spinlock.h new file mode 100644 index 0000000..80d42db --- /dev/null +++ b/spinlock.h @@ -0,0 +1,9 @@ +#ifndef SPINLOCK_H +#define SPINLOCK_H +#include +#include +typedef volatile int spinlock_t; +void spinlock_init(spinlock_t* lock); +unsigned long spinlock_acquire_irqsave(spinlock_t* lock); +void spinlock_release_irqrestore(spinlock_t* lock, unsigned long flags); +#endif \ No newline at end of file diff --git a/task.c b/task.c index 9931fcc..a5d3bcc 100644 --- a/task.c +++ b/task.c @@ -7,6 +7,9 @@ static task_t* current_task; static task_t* ready_queue; static int next_pid = 1; +task_t* get_current_task(void) { + return current_task; +} void tasking_install(void) { vga_print_string("Initializing multitasking... "); current_task = (task_t*)pmm_alloc_page(); @@ -15,10 +18,13 @@ void tasking_install(void) { current_task->state = TASK_RUNNING; current_task->kernel_stack = NULL; current_task->next = NULL; - ready_queue = current_task; + ready_queue = current_task; // This will be our idle task vga_print_string("[OK]\n"); } +void schedule_from_yield(void){ + asm volatile("int $0x20"); +} void create_task(char* name, void (*entry_point)(void)) { (void)name; // Name is for debugging, unused for now asm volatile("cli"); @@ -47,26 +53,54 @@ void create_task(char* name, void (*entry_point)(void)) { initial_regs->cs = 0x08; initial_regs->eflags = 0x202; new_task->regs.esp = (uint32_t)initial_regs; - new_task->next = NULL; - task_t* temp = ready_queue; - while(temp->next) { - temp = temp->next; + + // Insert into the circular ready queue + if (ready_queue == NULL) { + ready_queue = new_task; + new_task->next = new_task; // Point to itself + } else { + new_task->next = ready_queue->next; + ready_queue->next = new_task; } - temp->next = new_task; asm volatile("sti"); } void schedule(registers_t* r) { if (!current_task) return; + + // Save the state of the current task current_task->regs = *r; - if (!current_task->next) { - return; + + // If the current task is still running (and not blocked/sleeping), set it to ready + if (current_task->state == TASK_RUNNING) { + current_task->state = TASK_READY; } - task_t* prev_task = current_task; - current_task = current_task->next; - if (!current_task) { - current_task = ready_queue; + + // Find the next ready task + task_t* next_task = current_task; + do { + next_task = next_task->next; + if (next_task->state == TASK_READY) { + break; + } + } while (next_task != current_task); + + // If no other task is ready, and current is not ready, we might idle. + // But if we found a ready task (even if it's the current one), we switch. + if (next_task->state != TASK_READY) { + // If current_task is also not ready, we have a problem. + // For now, we just return, which continues the current context. + // In a real scenario, you'd switch to an idle task. + if(current_task->state != TASK_READY) { + current_task->state = TASK_RUNNING; // Prevent getting stuck + } + return; } + + // Switch to the next task + current_task = next_task; current_task->state = TASK_RUNNING; + + // Restore the state of the new current task *r = current_task->regs; } \ No newline at end of file diff --git a/task.h b/task.h index a6f73b6..da59e4e 100644 --- a/task.h +++ b/task.h @@ -6,17 +6,22 @@ typedef enum { TASK_RUNNING, TASK_READY, TASK_SLEEPING, - TASK_DEAD + TASK_DEAD, + TASK_BLOCKED, + TASK_WAITING, + TASK_KILLED, + TASK_ZOMBIE } task_state_t; typedef struct task { int id; registers_t regs; void* kernel_stack; task_state_t state; - struct task* next; + struct task* next; } task_t; void tasking_install(void); void create_task(char* name, void (*entry_point)(void)); void schedule(registers_t* r); +void schedule_and_release_lock(spinlock_t* lock, unsigned long flags); #endif \ No newline at end of file From c4794bbc985a64fcfe6a3ee1342dc6f642ec731a Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:21:40 +0530 Subject: [PATCH 09/18] Add files via upload --- boot.asm | 98 ++++++++++++++++++++ font.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++ font.h | 5 ++ graphics.c | 114 +++++++++++++++++++++++ graphics.h | 51 +++++++++++ kernel.c | 40 ++++++++- 6 files changed, 565 insertions(+), 3 deletions(-) create mode 100644 boot.asm create mode 100644 font.c create mode 100644 font.h create mode 100644 graphics.c create mode 100644 graphics.h diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..dabd58f --- /dev/null +++ b/boot.asm @@ -0,0 +1,98 @@ +bits 16 +org 0x7c00 +VBE_MAGIC equ 0x4F +VBE_GET_INFO equ 0x00 +VBE_GET_MODE_INFO equ 0x01 +VBE_SET_MODE equ 0x02 +TARGET_WIDTH equ 1280 +TARGET_HEIGHT equ 720 +TARGET_BPP equ 32 +;extern kernel_main + +start: + cli + cld + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov sp, 0x7c00 + in al, 0x92 + or al, 2 + out 0x92, al + mov ax, VBE_MAGIC + VBE_GET_INFO + mov di, vbe_info_block + int 0x10 + cmp ax, 0x004F + jne .graphics_error + mov cx, [vbe_info_block + 14] + mov si, [vbe_info_block + 16] +.mode_loop: + push cx + mov ax, VBE_MAGIC + VBE_GET_MODE_INFO + mov cx, [si] + mov di, mode_info_block + int 0x10 + cmp ax, 0x004F + jne .next_mode + cmp word [mode_info_block +18], TARGET_WIDTH + jne .next_mode + cmp word [mode_info_block +20], TARGET_HEIGHT + jne .next_mode + cmp word [mode_info_block +25], TARGET_BPP + jne .next_mode + mov ax, VBE_MAGIC + VBE_SET_MODE + mov bx, [si] + or bx, 1 << 14 ;For the Linear Frame Buffer (LFB) + int 0x10 + cmp ax, 0x004F + jne .graphics_error + mov edi, 0x8000 + mov esi, mode_info_block + mov ecx, 256 + rep movsb + jmp .continue_boot +.next_mode: + add si, 2 + pop cx + loop .mode_loop +.graphics_error: + cli + hlt +.continue_boot + lgdt [gdt_descriptor] + mov eax, cr0 + or eax, 1 + mov cr0, eax + jmp 0x08:start_protected_mode + +bits 32 +start_protected_mode: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + mov esp, 0x90000 ; Set stack pointer to safe location + push dword 0x8000 + call kernel_main + cli + hlt + jmp $ +; GDT for bootloader +gdt_start: + dd 0x0, 0x0 + dw 0xFFFF, 0x0000, 0x9A, 0xCF, 0x00 + dw 0xFFFF, 0x0000, 0x92, 0xCF, 0x00 +gdt_end: +gdt_descriptor: + dw gdt_end - gdt_start - 1 ; Limit + dd gdt_start +bss_start: + vbe_info_block resb 512 + mode_info_block resb 256 +bss_end: +; Boot signature +times 510-($-$$) db 0 +dw 0xAA55 \ No newline at end of file diff --git a/font.c b/font.c new file mode 100644 index 0000000..b091638 --- /dev/null +++ b/font.c @@ -0,0 +1,260 @@ +#include "font.h" + +const uint8_t font[256][16] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x00 Null + {0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x01 SOH + {0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x02 STX + {0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x03 ETX + {0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x04 EOT + {0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x05 ENQ + {0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x06 ACK + {0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x07 BEL + {0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x08 BS + {0x00, 0x3C, 0x7E, 0x7E, 0x7E, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x09 HT + {0x00, 0x3C, 0x7E, 0x7E, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0A LF + {0x0C, 0x18, 0x30, 0x7E, 0x7E, 0x7E, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0B VT + {0x38, 0x7C, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0C FF + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0D CR + {0x0C, 0x1E, 0x3F, 0x3F, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0E SO + {0x38, 0x7C, 0xFE, 0x38, 0x38, 0xFE, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0F SI + {0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x10 DLE + {0x30, 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x11 DC1 + {0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x12 DC2 + {0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x13 DC3 + {0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x14 DC4 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x15 NAK + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x16 SYN + {0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x17 ETB + {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x18 CAN + {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x19 EM + {0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1A SUB + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1B ESC + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1C FS + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1D GS + {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1E RS + {0x18, 0x18, 0x18, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x1F US + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x20 Space + {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x21 ! + {0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x22 " + {0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x23 # + {0x38, 0x7C, 0xA0, 0x78, 0x2C, 0xF8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x24 $ + {0xC6, 0xC6, 0x0C, 0x18, 0x30, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x25 % + {0x38, 0x7C, 0x80, 0x80, 0x7C, 0x86, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x26 & + {0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x27 ' + {0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x28 ( + {0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x29 ) + {0x00, 0x6C, 0x38, 0xFE, 0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2A * + {0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2B + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2C , + {0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2D - + {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2E . + {0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x2F / + {0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x30 0 + {0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x31 1 + {0x7C, 0x82, 0x02, 0x7C, 0x80, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x32 2 + {0x7C, 0x02, 0x02, 0x3C, 0x02, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x33 3 + {0x84, 0x84, 0x84, 0xFE, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x34 4 + {0xFE, 0x80, 0x80, 0xFC, 0x02, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x35 5 + {0x7C, 0x80, 0x80, 0xFC, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x36 6 + {0xFE, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x37 7 + {0x7C, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x38 8 + {0x7C, 0x82, 0x82, 0x7E, 0x02, 0x02, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x39 9 + {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3A : + {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3B ; + {0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3C < + {0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3D = + {0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3E > + {0x7C, 0x82, 0x02, 0x0C, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x3F ? + {0x7C, 0x82, 0xBA, 0xAA, 0xAA, 0xB8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x40 @ + {0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x41 A + {0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x42 B + {0x7C, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x43 C + {0xF8, 0x84, 0x82, 0x82, 0x82, 0x84, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x44 D + {0xFE, 0x80, 0x80, 0xF8, 0x80, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x45 E + {0xFE, 0x80, 0x80, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x46 F + {0x7C, 0x82, 0x80, 0x8E, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x47 G + {0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x48 H + {0x7C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x49 I + {0x0E, 0x02, 0x02, 0x02, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4A J + {0x82, 0x84, 0x88, 0xF0, 0x88, 0x84, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4B K + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4C L + {0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4D M + {0x82, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4E N + {0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x4F O + {0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x50 P + {0x7C, 0x82, 0x82, 0x82, 0x8A, 0x84, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x51 Q + {0xFC, 0x82, 0x82, 0xFC, 0x88, 0x84, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x52 R + {0x7C, 0x80, 0x80, 0x7C, 0x02, 0x02, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x53 S + {0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x54 T + {0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x55 U + {0x82, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x56 V + {0x82, 0x82, 0x82, 0x92, 0x92, 0xAA, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x57 W + {0x82, 0x82, 0x44, 0x38, 0x44, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x58 X + {0x82, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x59 Y + {0xFE, 0x04, 0x08, 0x10, 0x20, 0x40, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5A Z + {0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5B [ + {0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5C '\' + {0x7C, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5D ] + {0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5E ^ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x5F _ + {0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x60 ` + {0x00, 0x00, 0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x61 a + {0x80, 0x80, 0xF8, 0x84, 0x84, 0x84, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x62 b + {0x00, 0x00, 0x78, 0x80, 0x80, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x63 c + {0x04, 0x04, 0x7C, 0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x64 d + {0x00, 0x00, 0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x65 e + {0x0C, 0x10, 0x10, 0xF8, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x66 f + {0x00, 0x00, 0x7C, 0x84, 0x84, 0x7C, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x67 g + {0x80, 0x80, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x68 h + {0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x69 i + {0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x8C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6A j + {0x80, 0x80, 0x88, 0x90, 0xA0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6B k + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6C l + {0x00, 0x00, 0xCC, 0xAA, 0xAA, 0xAA, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6D m + {0x00, 0x00, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6E n + {0x00, 0x00, 0x78, 0x84, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x6F o + {0x00, 0x00, 0xF8, 0x84, 0x84, 0xF8, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x70 p + {0x00, 0x00, 0x7C, 0x84, 0x84, 0x7C, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x71 q + {0x00, 0x00, 0xAC, 0x94, 0x90, 0x90, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x72 r + {0x00, 0x00, 0x70, 0x88, 0x70, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x73 s + {0x10, 0x10, 0xF8, 0x10, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x74 t + {0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x75 u + {0x00, 0x00, 0x84, 0x84, 0x48, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x76 v + {0x00, 0x00, 0x84, 0x84, 0x94, 0x94, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x77 w + {0x00, 0x00, 0x84, 0x50, 0x28, 0x50, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x78 x + {0x00, 0x00, 0x84, 0x84, 0x84, 0x7C, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x79 y + {0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7A z + {0x1C, 0x30, 0x30, 0x60, 0x30, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7B { + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7C | + {0xE0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7D } + {0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7E ~ + {0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x7F DEL + {0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x80 Ç + {0x84, 0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x81 ü + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x82 é + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x83 â + {0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x84 ä + {0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x85 à + {0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x86 å + {0x78, 0x80, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x87 ç + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x88 ê + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x89 ë + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8A è + {0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8B ï + {0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8C î + {0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8D ì + {0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8E Ä + {0x78, 0x84, 0x84, 0x78, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x8F Å + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x90 É + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x91 æ + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x92 Æ + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x93 ô + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x94 ö + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x95 ò + {0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x96 û + {0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x97 ù + {0x84, 0x84, 0x84, 0x7C, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x98 ÿ + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x99 Ö + {0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9A Ü + {0x7C, 0x80, 0xFC, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9B ø + {0xFC, 0x80, 0x80, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9C £ + {0x7C, 0x80, 0xFC, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9D Ø + {0x82, 0x44, 0x38, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9E × + {0x80, 0x80, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0x9F ƒ + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA0 á + {0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA1 í + {0x78, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA2 ó + {0x84, 0x84, 0x84, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA3 ú + {0x82, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA4 ñ + {0x82, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA5 Ñ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA6 ª + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA7 º + {0x7C, 0x82, 0x02, 0x0C, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA8 ¿ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA9 ® + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAA ¬ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAB ½ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAC ¼ + {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAD ¡ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAE « + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xAF » + {0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB0 ░ + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB1 ▒ + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB2 ▓ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB3 │ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB4 ┤ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB5 ╡ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB6 ╢ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB7 ╖ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB8 ╕ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xB9 ╣ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBA ║ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBB ╗ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBC ╝ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBD ╜ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBE ╛ + {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xBF ┐ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC0 └ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC1 ┴ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC2 ┬ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC3 ├ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC4 ─ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC5 ┼ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC6 ╞ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC7 ╟ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC8 ╚ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xC9 ╔ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCA ╩ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCB ╦ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCC ╠ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCD ═ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCE ╬ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xCF ╧ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD0 ╨ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD1 ╤ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD2 ╥ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD3 ╙ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD4 ╘ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD5 ╒ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD6 ╓ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD7 ╫ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD8 ╪ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xD9 ┘ + {0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDA ┌ + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDB █ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDC ▄ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDD ▌ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDE ▐ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xDF ▀ + {0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE0 α + {0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE1 ß + {0x7C, 0x82, 0x80, 0x8E, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE2 Γ + {0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE3 π + {0xFE, 0x80, 0x80, 0xF8, 0x80, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE4 Σ + {0xFE, 0x80, 0x80, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE5 σ + {0x7C, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE6 µ + {0x82, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE7 τ + {0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE8 Φ + {0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xE9 Θ + {0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xEA Ω + {0x82, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xEB δ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xEC ∞ + {0x82, 0x82, 0x44, 0x38, 0x44, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xED φ + {0x78, 0x84, 0xF4, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xEE ε + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xEF ∩ + {0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF0 ≡ + {0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF1 ± + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF2 ≥ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF3 ≤ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF4 ⌠ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF5 ⌡ + {0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF6 ÷ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF7 ≈ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF8 ° + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xF9 ∙ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFA · + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFB √ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFC ⁿ + {0x7C, 0x82, 0x02, 0x7C, 0x80, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFD ² + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFE ■ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0xFF (NBSP) +}; \ No newline at end of file diff --git a/font.h b/font.h new file mode 100644 index 0000000..416bb78 --- /dev/null +++ b/font.h @@ -0,0 +1,5 @@ +#ifndef FONT_H +#define FONT_H +#include +extern const uint8_t font[]; +#endif \ No newline at end of file diff --git a/graphics.c b/graphics.c new file mode 100644 index 0000000..7601359 --- /dev/null +++ b/graphics.c @@ -0,0 +1,114 @@ +#include "graphics.h" +#define FONT_TRANSPARENT_COLOR 0xFFFF00FF // Magenta as transparent color +void put_pixel(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t color) { + if (x >= fb->width || y >= fb->height) return; + uint8_t* pixel = (uint8_t*)fb->address + y * fb->pitch + x * fb->bytesPerPixel; + + if (fb->bitsPerPixel == 24) { + pixel[0] = color & 0xFF; // Blue + pixel[1] = (color >> 8) & 0xFF; // Green + pixel[2] = (color >> 16) & 0xFF; // Red + } else if (fb->bitsPerPixel == 32) { + *(uint32_t*)pixel = color; + } +} +void clear_screen(FrameBuffer* fb, uint32_t color) { + for (uint32_t y = 0; y < fb->height; y++) { + for (uint32_t x = 0; x < fb->width; x++) { + put_pixel(fb, x, y, color); + } + } +} +void draw_circle(FrameBuffer* fb, uint32_t xc, uint32_t yc, uint32_t r, uint32_t color) { + int32_t x = (int32_t)r; + int32_t y = 0; + int32_t err = 3 - (2 * (int32_t)r); + + while (x >= y) { + put_pixel(fb, xc + x, yc + y, color); + put_pixel(fb, xc + y, yc + x, color); + put_pixel(fb, xc - y, yc + x, color); + put_pixel(fb, xc - x, yc + y, color); + put_pixel(fb, xc - x, yc - y, color); + put_pixel(fb, xc - y, yc - x, color); + put_pixel(fb, xc + y, yc - x, color); + put_pixel(fb, xc + x, yc - y, color); + + if (err > 0) { + err += 4 * (y - x) + 10; + x--; + } else { + err += 4 * y + 6; + } + y++; + } +} +void draw_line(FrameBuffer* fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color) { + int32_t dx = (x1 > x0) ? (x1 - x0) : (x0 - x1); + int32_t dy = (y1 > y0) ? (y1 - y0) : (y0 - y1); + int32_t sx = (x0 < x1) ? 1 : -1; + int32_t sy = (y0 < y1) ? 1 : -1; + int32_t err = dx - dy; + while (1) { + if (x0 >= 0 && (uint32_t)x0 < fb->width && y0 >= 0 && (uint32_t)y0 < fb->height) { + put_pixel(fb, (uint32_t)x0, (uint32_t)y0, color); + } + if (x0 == x1 && y0 == y1) break; + int32_t e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } +} +void draw_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color) { + if (width == 0 || height == 0) return; + + uint32_t x1 = x + width - 1; + uint32_t y1 = y + height - 1; + draw_line(fb, x, y, x1, y, color); // Top + draw_line(fb, x, y1, x1, y1, color); // Bottom + draw_line(fb, x, y, x, y1, color); // Left + draw_line(fb, x1, y, x1, y1, color); // Right +} +void fill_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color) { + for (uint32_t j = y; j < y + height; j++) { + for (uint32_t i = x; i < x + width; i++) { + put_pixel(fb, i, j, color); + } + } +} +void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, uint32_t x, uint32_t y, uint32_t color) { + for (uint32_t j = 0; j < bmp->height; j++) { + for (uint32_t i = 0; i < bmp->width; i++) { + uint8_t pixel = *((uint8_t*)bmp->data + j * bmp->width + i); + if (pixel) { // Assuming non-zero pixel is to be drawn + put_pixel(fb, x + i, y + j, color); + } + } + } +} +void draw_char(FrameBuffer* fb, Font* font, char c, uint32_t x, uint32_t y, uint32_t color) { + if (c < 32 || c > 126) return; + Bitmap* bmp = &font->bitmap[c - 32]; + for (uint32_t j = 0; j < bmp->height; j++) { + for (uint32_t i = 0; i < bmp->width; i++) { + uint8_t pixel = *((uint8_t*)bmp->data + j * bmp->width + i); + if (pixel && pixel != FONT_TRANSPARENT_COLOR) { // Skip transparent pixels + put_pixel(fb, x + i, y + j, color); + } + } + } +} +void draw_string(FrameBuffer* fb, Font* font, const char* str, uint32_t x, uint32_t y, uint32_t color) { + while (*str) { + draw_char(fb, font, *str, x, y, color); + x += font->char_width; + str++; + } +} +#undef FONT_TRANSPARENT_COLOR \ No newline at end of file diff --git a/graphics.h b/graphics.h new file mode 100644 index 0000000..05624fe --- /dev/null +++ b/graphics.h @@ -0,0 +1,51 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H +#include +typedef struct __attribute__((packed)){ + uint16_t attributes; + uint8_t windowA, windowB; + uint16_t granularity; + uint16_t windowSize; + uint16_t windowASegment, windowBSegment; + uint32_t winFuncPtr; + uint16_t pitch; + uint16_t resolution_x, resolution_y; + uint8_t wChar, yChar, planes, bitsPerPixel,banks; + uint8_t memoryModel, bankSize, imagePages; + uint8_t reserved1; + uint8_t redMask, redMaskPosition; + uint8_t greenMask, greenMaskPosition; + uint8_t blueMask, blueMaskPosition; + uint8_t rsvdMask, rsvdMaskPosition; + uint8_t directColorAttributes; + uint32_t physbase; + uint32_t reserved2; + uint16_t reserved3; +} VbeModeInfo; +typedef struct{ + void* address; + uint32_t width; + uint32_t height; + uint32_t pitch; + uint8_t bitsPerPixel; + uint8_t bytesPerPixel; +} FrameBuffer; +typedef struct { + uint32_t width; + uint32_t height; + uint8_t data; +}Bitmap; +typedef struct { + Bitmap* bitmap; + uint32_t char_width; + uint32_t char_height; +}Font; +void clear_screen(FrameBuffer* fb, uint32_t color); +void put_pixel(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t color); +void draw_line(FrameBuffer* fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t color); +void draw_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color); +void draw_circle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t radius, uint32_t color); +void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, uint32_t x, uint32_t y, uint32_t color); +void draw_char(FrameBuffer* fb, Font* font, char c, uint32_t x, uint32_t y, uint32_t color); +void draw_string(FrameBuffer* fb, Font* font, const char* str, uint32_t x, uint32_t y, uint32_t color); +#endif \ No newline at end of file diff --git a/kernel.c b/kernel.c index cfb7697..7fe89f6 100644 --- a/kernel.c +++ b/kernel.c @@ -1,4 +1,5 @@ #include +#include "graphics.h" #include "vga.h" #include "idt.h" #include "gdt.h" @@ -17,6 +18,26 @@ void counter_task(){ vga_putentryat('A' + (i++%26),0x0F,79,0); } } + +// Assuming vbe_mode_info is provided by the bootloader. +// This is a common structure for VBE mode information. +typedef struct { + uint16_t attributes; + uint8_t window_a, window_b; + uint16_t granularity; + uint16_t window_size; + uint16_t segment_a, segment_b; + uint32_t win_func_ptr; + uint16_t pitch, resolution_x, resolution_y; + uint8_t chars_x, chars_y, planes, bitsPerPixel, banks; + uint8_t memory_model, bank_size, image_pages; + uint8_t reserved0; + // ... other fields might follow + uint32_t physbase; +} __attribute__((packed)) vbe_mode_info_t; + +extern vbe_mode_info_t vbe_mode_info; + void kernel_main(void) { vga_init(); vga_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK)); @@ -42,10 +63,23 @@ void kernel_main(void) { vga_print_string("\nKernel initialization complete!\n"); vga_print_string("Security features: Buffer overflow protection, bounds checking\n"); vga_print_string("Starting shell...\n\n"); - - shell_init(); + FrameBuffer fb; + fb.address=(void*)vbe_mode_info.physbase; + fb.width=vbe_mode_info.resolution_x; + fb.height=vbe_mode_info.resolution_y; + fb.pitch=vbe_mode_info.pitch; + fb.bitsPerPixel=vbe_mode_info.bitsPerPixel; + fb.bytesPerPixel = vbe_mode_info.bitsPerPixel / 8; + if (fb.bitsPerPixel != 24) { + vga_print_string("Error: Graphics mode is not 24-bit color depth!\n"); + for(;;) { asm volatile("cli; hlt"); } + } + uint32_t xc = fb.width / 2; + uint32_t yc = fb.height / 2; - // Main kernel loop - wait for interrupts + clear_screen(&fb, 0x000000); + draw_circle(&fb, xc, yc, 50, 0xFFFFFF); + //Scheduler takes over, chillax!! while(1) { asm volatile("hlt"); } From 451f3e81097dedd2c47b5b29b3a43b117d96e4e4 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 14 Oct 2025 19:51:38 +0530 Subject: [PATCH 10/18] Add files via upload --- kernel.c | 58 ++++++++++- widget.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ widget.h | 71 +++++++++++++ window.c | 173 ++++++++++++++++++++++++++++++++ window.h | 28 ++++++ 5 files changed, 624 insertions(+), 3 deletions(-) create mode 100644 widget.c create mode 100644 widget.h create mode 100644 window.c create mode 100644 window.h diff --git a/kernel.c b/kernel.c index 7fe89f6..d53a123 100644 --- a/kernel.c +++ b/kernel.c @@ -8,19 +8,40 @@ #include "timer.h" #include "paging.h" //#include "pci.h" +#include "graphics.h" +#include "widget.h" +#include "font.h" +#include #include "NIC.h" #include "pmm.h" #include "task.h" #include "syscall.h" +#include "window.h" void counter_task(){ int i=0; while(1){ vga_putentryat('A' + (i++%26),0x0F,79,0); } } - -// Assuming vbe_mode_info is provided by the bootloader. -// This is a common structure for VBE mode information. +Widget* widget_list_head=NULL; +Window* window_list_head=NULL; +Window* window_list_tail=NULL; +void on_my_button_click(){ + if(!g_widget_font)return; + ButtonData* data=(ButtonData*)widget_list_head->data; + if(!data)return; + data->bg_color=data->press_color; + data->border_color=data->press_border; + //vga_print_string("Button clicked!\n"); +} +void on_my_button_release(){ + if(!g_widget_font)return; + ButtonData* data=(ButtonData*)widget_list_head->data; + if(!data)return; + data->bg_color=data->base_color; + data->border_color=data->border_color; + //vga_print_string("Button released!\n"); +} typedef struct { uint16_t attributes; uint8_t window_a, window_b; @@ -70,6 +91,11 @@ void kernel_main(void) { fb.pitch=vbe_mode_info.pitch; fb.bitsPerPixel=vbe_mode_info.bitsPerPixel; fb.bytesPerPixel = vbe_mode_info.bitsPerPixel / 8; + Font my_font; + my_font.char_width=8; + my_font.char_height=16; + my_font.bitmap=NULL; // Assume a function to load a bitmap font + if (fb.bitsPerPixel != 24) { vga_print_string("Error: Graphics mode is not 24-bit color depth!\n"); for(;;) { asm volatile("cli; hlt"); } @@ -79,6 +105,32 @@ void kernel_main(void) { clear_screen(&fb, 0x000000); draw_circle(&fb, xc, yc, 50, 0xFFFFFF); + Window* main_window = create_window(100, 100, 400, 300, (char*[]){"Main Window"}, true); + if (!main_window) { + vga_print_string("Error: Failed to create main window!\n"); + for(;;) { asm volatile("cli; hlt"); } + } + Widget* label = create_label(20, 40, 200, 30, "Hello, SimpleOS!", 0x000000); + if (!label) { + vga_print_string("Error: Failed to create label widget!\n"); + for(;;) { asm volatile("cli; hlt"); } + } + Widget* button = create_button(100, 100, 100, 50, "Click Me", 0x0000FF, 0x00FF00, 0xFF0000, 0x000000, 2, 0xFFFFFF, 0xFFFF00, 0x00FFFF); + if (!button) { + vga_print_string("Error: Failed to create button widget!\n"); + for(;;) { asm volatile("cli; hlt"); } + } + widget_add(&widget_list_head, label); + widget_add(&widget_list_head, button); + window_add_widget(main_window, label); + window_add_widget(main_window, button); + window_draw(main_window, &fb); + button->onClick = (void (*)(struct Widget*, int, int, int))on_my_button_click; + button->onRelease = (void (*)(struct Widget*, int, int, int))on_my_button_release; + window_list_head = main_window; + window_list_tail = main_window; + init_widget_system(); + widget_set_font(&my_font); //Scheduler takes over, chillax!! while(1) { asm volatile("hlt"); diff --git a/widget.c b/widget.c new file mode 100644 index 0000000..6c1cfa3 --- /dev/null +++ b/widget.c @@ -0,0 +1,297 @@ +#include "widget.h" +#include +#include +#include "graphics.h" +#include "font.h" +#include "keyboard.h" +#include "timer.h" +#include "memory.h" +#include "shell.h" +#include "pci.h" +static Font* g_widget_font=NULL; +void widget_set_font(Font* font){ + g_widget_font=font; +} +void draw_label(Widget* self,FrameBuffer* fb){ + if(!g_widget_font)return; + LabelData* data=(LabelData*)self->data; + if(!data||!data->text)return; + draw_string(fb,self->x,self->y,data->text,data->color,g_widget_font); +} +void update_label(Widget* self,FrameBuffer* fb){ + // Labels are static, no update needed +} +void draw_button(Widget* self,FrameBuffer* fb){ + if(!g_widget_font)return; + ButtonData* data=(ButtonData*)self->data; + if(!data||!data->text)return; + // Draw button background + for(int y=0;yheight;y++){ + for(int x=0;xwidth;x++){ + uint32_t color=data->bg_color; + if(xwidth/2){ + if(yheight/2){ + color=data->base_color; + }else{ + color=data->hover_color; + } + }else{ + if(yheight/2){ + color=data->hover_color; + }else{ + color=data->base_color; + } + } + fb_set_pixel(fb,self->x+x,self->y+y,color); + } + } + // Draw button border + for(int i=0;iborder_width;i++){ + for(int y=i;yheight-i;y++){ + for(int x=i;xwidth-i;x++){ + uint32_t color=data->border_color; + if(x==i||x==self->width-i-1||y==i||y==self->height-i-1){ + fb_set_pixel(fb,self->x+x,self->y+y,color); + } + } + } + } + // Draw button text (centered) + int text_width=strlen(data->text)*g_widget_font->char_width; + int text_height=g_widget_font->char_height; + int text_x=self->x+self->width/2-text_width/2; + int text_y=self->y+self->height/2-text_height/2; + draw_string(fb,text_x,text_y,data->text,data->text_color,g_widget_font); +} +void update_button(Widget* self,FrameBuffer* fb){ + // Buttons are static, no update needed +} +void draw_textbox(Widget* self,FrameBuffer* fb){ + if(!g_widget_font)return; + // Placeholder for textbox drawing + // ... +} +void update_textbox(Widget* self,FrameBuffer* fb){ + // Placeholder for textbox update + // ... +} +void draw_scrollbar(Widget* self,FrameBuffer* fb){ + // Placeholder for scrollbar drawing + // ... +} +void update_scrollbar(Widget* self,FrameBuffer* fb){ + // Placeholder for scrollbar update + // ... +} +void handle_button_click(Widget* self,int mouse_x,int mouse_y,int button){ + ButtonData* data=(ButtonData*)self->data; + if(!data)return; + // Change button color on click + if(button==1){ // Left click + data->bg_color=data->press_color; + data->border_color=data->press_border; + } +} +void handle_button_release(Widget* self,int mouse_x,int mouse_y,int button){ + ButtonData* data=(ButtonData*)self->data; + if(!data)return; + if(button==1){ // Left click + data->bg_color=data->base_color; + data->border_color=data->border_color; + } +} +void handle_button_hover(Widget* self,int mouse_x,int mouse_y){ + ButtonData* data=(ButtonData*)self->data; + if(!data)return; + // Change button color on hover + data->bg_color=data->hover_color; + data->border_color=data->hover_border; +} +void handle_button_leave(Widget* self,int mouse_x,int mouse_y){ + ButtonData* data=(ButtonData*)self->data; + if(!data)return; + // Revert button color when not hovering + data->bg_color=data->base_color; + data->border_color=data->border_color; +} +void widget_draw(Widget* widget,FrameBuffer* fb){ + if(widget&&widget->draw){ + widget->draw(widget,fb); + } +} +void widget_update(Widget* widget,FrameBuffer* fb){ + if(widget&&widget->update){ + widget->update(widget,fb); + } +} +void widget_handle_event(Widget* widget,int mouse_x,int mouse_y,int event){ + if(widget&&widget->handle_event){ + widget->handle_event(widget,mouse_x,mouse_y,event); + } +} +void widget_add(Widget** head,Widget* new_widget){ + if(!head||!new_widget)return; + new_widget->next=*head; + *head=new_widget; +} +void widget_remove(Widget** head,Widget* widget){ + if(!head||!widget)return; + if(*head==widget){ + *head=widget->next; + return; + } + Widget* current=*head; + while(current&¤t->next!=widget){ + current=current->next; + } + if(current){ + current->next=widget->next; + } +} +void widget_free(Widget* widget){ + if(!widget)return; + if(widget->data)free(widget->data); + free(widget); +} +void widget_free_all(Widget** head){ + if(!head)return; + Widget* current=*head; + while(current){ + Widget* next=current->next; + widget_free(current); + current=next; + } + *head=NULL; +} +void widget_draw_all(Widget* head,FrameBuffer* fb){ + Widget* current=head; + while(current){ + widget_draw(current,fb); + current=current->next; + } +} +void widget_update_all(Widget* head,FrameBuffer* fb){ + Widget* current=head; + while(current){ + widget_update(current,fb); + current=current->next; + } +} +void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ + Widget* current=head; + while(current){ + widget_handle_event(current,mouse_x,mouse_y,event); + current=current->next; + } +} +Widget* create_label(int x,int y,int width,int height,char* text,uint32_t color){ + LabelData* data=(LabelData*)malloc(sizeof(LabelData)); + if(!data)return NULL; + data->text=text; + data->color=color; + Widget* widget=(Widget*)malloc(sizeof(Widget)); + if(!widget){ + free(data); + return NULL; + } + widget->x=x; + widget->y=y; + widget->width=width; + widget->height=height; + widget->data=data; + widget->draw=draw_label; + widget->update=update_label; + return widget; +} +Widget* create_button(int x,int y,int width,int height,char* text,uint32_t base_color,uint32_t hover_color,uint32_t press_color,uint32 _t border_color,int border_width,uint32_t text_color,uint32_t press_border,uint32_t hover_border){ + ButtonData* data=(ButtonData*)malloc(sizeof(ButtonData)); + if(!data)return NULL; + data->text=text; + data->base_color=base_color; + data->hover_color=hover_color; + data->press_color=press_color; + data->border_color=border_color; + data->border_width=border_width; + data->text_color=text_color; + data->press_border=press_border; + data->hover_border=hover_border; + Widget* widget=(Widget*)malloc(sizeof(Widget)); + if(!widget){ + free(data); + return NULL; + } + widget->x=x; + widget->y=y; + widget->width=width; + widget->height=height; + widget->data=data; + widget->draw=draw_button; + widget->update=update_button; + widget->onClick=handle_button_click; + widget->onRelease=handle_button_release; + widget->onHover=handle_button_hover; + widget->onMove=NULL; + return widget; +} +Widget* create_textbox(int x,int y,int width,int height,char* placeholder,uint32_t bg_color,uint32_t text_color){ + TextboxData* data=(TextboxData*)malloc(sizeof(TextboxData)); + if(!data)return NULL; + data->placeholder=placeholder; + data->bg_color=bg_color; + data->text_color=text_color; + data->text=(char*)malloc(256); // Fixed size for simplicity + if(!data->text){ + free(data); + return NULL; + } + data->text[0]='\0'; + Widget* widget=(Widget*)malloc(sizeof(Widget)); + if(!widget){ + free(data->text); + free(data); + return NULL; + } + widget->x=x; + widget->y=y; + widget->width=width; + widget->height=height; + widget->data=data; + widget->draw=draw_textbox; + widget->update=update_textbox; + return widget; +} +Widget* create_scrollbar(int x,int y,int width,int height,uint32_t bg_color,uint32_t thumb_color){ + ScrollbarData* data=(ScrollbarData*)malloc(sizeof(ScrollbarData)); + if(!data)return NULL; + data->bg_color=bg_color; + data->thumb_color=thumb_color; + data->thumb_pos=0; + data->thumb_size=height/4; // Example size + Widget* widget=(Widget*)malloc(sizeof(Widget)); + if(!widget){ + free(data); + return NULL; + } + widget->x=x; + widget->y=y; + widget->width=width; + widget->height=height; + widget->data=data; + widget->draw=draw_scrollbar; + widget->update=update_scrollbar; + return widget; +} +void init_widget_system(){ + // Initialize default font + g_widget_font=load_font("default_font_path"); // Placeholder path +} + if(!g_widget_font){ + // Fallback to built-in font + g_widget_font=get_builtin_font(); + } + if(!g_widget_font){ + // If still no font, log error + log_error("Failed to load widget font"); + } + // Initialize other widget system components if needed + \ No newline at end of file diff --git a/widget.h b/widget.h new file mode 100644 index 0000000..d5f73b3 --- /dev/null +++ b/widget.h @@ -0,0 +1,71 @@ +#ifndef WIDGET_H +#define WIDGET_H +#include "graphics.h" +#include +struct Widget; +typedef enum { + WIDGET_LABEL, + WIDGET_BUTTON, + WIDGET_CHECKBOX, + WIDGET_RADIOBUTTON, + WIDGET_SLIDER, + WIDGET_SCROLLBAR, + WIDGET_LISTBOX, + WIDGET_PANEL, + WIDGET_TEXTBOX, + WIDGET_TEXTAREA, + WIDGET_COMBOBOX, + WIDGET_MENU, + WIDGET_TABLE, + WIDGET_TREE, + WIDGET_GRAPH, + WIDGET_DIALOG, + WIDGET_SPINNER, + WIDGET_CANVAS, + WIDGET_PROGRESSBAR, + WIDGET_FILECHOOSER, + WIDGET_COLORCHOOSER, + WIDGET_FONTCHOOSER, + WIDGET_SLIDER, + WIDGET_MENU, + WIDGET_TOGGLEBUTTON, + WIDGET_RADIOGROUP, + WIDGET_VOICEINPUT +}WidgetType; +typedef struct Widget{ + WidgetType type; + int x,y,width,height; + void (*draw)(struct Widget* self,FrameBuffer* fb); + void (*update)(struct Widget* self,FrameBuffer* fb); + void (*onClick)(struct Widget* self,int mouse_x,int mouse_y,int button); + void (*onHover)(struct Widget* self,int mouse_x,int mouse_y); + void (*onRelease)(struct Widget* self,int mouse_x,int mouse_y,int button); + void (*onMove)(struct Widget* self,int mouse_x,int mouse_y); + void* data; + struct Widget* next; + +}Widget; +typedef struct{ + char* text; + uint32_t color; +} LabelData; +typedef struct{ + char* text; + uint32_t color; + uint32_t bg_color; + uint32_t border_color; + int border_width; + uint32_t base_color; + int base_width; + uint32_t text_color; + uint32_t press_color; + uint32_t press_border; + uint32_t hover_color; + uint32_t hover_border; +} ButtonData; +//Below are the constructors. +Widget* create_label(int x,int y,int width,int height,char* text,uint32_t color); +Widget* create_button(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width,uint32_t base_color,int base_width,uint32_t text_color,uint32_t press_color,uint32_t press_border,uint32_t hover_color,uint32_t hover_border); +Widget* create_checkbox(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width); + +#endif \ No newline at end of file diff --git a/window.c b/window.c new file mode 100644 index 0000000..134317d --- /dev/null +++ b/window.c @@ -0,0 +1,173 @@ +#include "window.h" +#include +#include +#define WINDOW_BG_COLOR 0xECECEC +#define TITLE_BAR_COLOR 0x2C2C2C +#define TITLE_TEXT_COLOR 0xFFFFFF +#define TITLE_BAR_HEIGHT 25 +extern Font* g_widget_font; +Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar){ + Window* window=(Window*)malloc(sizeof(Window)); + if(!window)return NULL; + window->x=x; + window->y=y; + window->width=width; + window->height=height; + window->title=title; + window->has_title_bar=has_title_bar; + window->child_widgets_head=NULL; + window->child_widgets_tail=NULL; + window->next=NULL; + window->prev=NULL; + window->parent=NULL; + window->child=NULL; + window->sibling=NULL; + return window; +} +void window_add_widget(Window* window,Widget* widget){ + if(!window||!widget)return; + if(!window->child_widgets_head){ + window->child_widgets_head=widget; + window->child_widgets_tail=widget; + }else{ + window->child_widgets_tail->next=widget; + window->child_widgets_tail=widget; + } + widget->next=NULL; // Ensure the new widget's next is NULL +} +void window_remove_widget(Window* window,Widget* widget){ + if(!window||!widget||!window->child_widgets_head)return; + if(window->child_widgets_head==widget){ + window->child_widgets_head=widget->next; + if(window->child_widgets_tail==widget){ + window->child_widgets_tail=NULL; + } + return; + } + Widget* current=window->child_widgets_head; + while(current&¤t->next!=widget){ + current=current->next; + } + if(current){ + current->next=widget->next; + if(window->child_widgets_tail==widget){ + window->child_widgets_tail=current; + } + } +} +void window_free_widgets(Window* window){ + if(!window)return; + Widget* current=window->child_widgets_head; + while(current){ + Widget* next=current->next; + if(current->data)free(current->data); + free(current); + current=next; + } + window->child_widgets_head=NULL; + window->child_widgets_tail=NULL; +} +void window_free(Window* window){ + if(!window)return; + window_free_widgets(window); + free(window); +} +void window_draw(Window* window,FrameBuffer* fb){ + if(!window)return; + // Draw window background + for(int y=0;yheight;y++){ + for(int x=0;xwidth;x++){ + fb_set_pixel(fb,window->x+x,window->y+y,WINDOW_BG_COLOR); + } + } + // Draw title bar if present + if(window->has_title_bar&&window->title){ + for(int y=0;ywidth;x++){ + fb_set_pixel(fb,window->x+x,window->y+y,TITLE_BAR_COLOR); + } + } + // Draw title text (centered) + if(g_widget_font){ + int text_width=strlen(*window->title)*g_widget_font->char_width; + int text_height=g_widget_font->char_height; + int text_x=window->x+window->width/2-text_width/2; + int text_y=window->y+(TITLE_BAR_HEIGHT-text_height)/2; + draw_string(fb,text_x,text_y,*window->title,TITLE_TEXT_COLOR,g_widget_font); + } + } + // Draw child widgets + widget_draw_all(window->child_widgets_head,fb); +} +void window_update(Window* window,FrameBuffer* fb){ + if(!window)return; + widget_update_all(window->child_widgets_head,fb); +} +void window_handle_event(Window* window,int mouse_x,int mouse_y,int event){ + if(!window)return; + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,event); +} +void window_on_click(Window* window,int mouse_x,int mouse_y,int button){ + if(!window)return; + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,1); // 1 for click +} +void window_on_release(Window* window,int mouse_x,int mouse_y,int button){ + if(!window)return; + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,2); // 2 for release +} +void window_on_hover(Window* window,int mouse_x,int mouse_y){ + if(!window)return; + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,3); // 3 for hover +} +void window_on_move(Window* window,int mouse_x,int mouse_y){ + if(!window)return; + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,4); // 4 for move +} +void widget_draw_all(Widget* head,FrameBuffer* fb){ + Widget* current=head; + while(current){ + widget_draw(current,fb); + current=current->next; + } +} +void widget_draw(Widget* widget,FrameBuffer* fb){ + if(!widget||!widget->draw)return; + widget->draw(widget,fb); +} +void widget_update(Widget* widget,FrameBuffer* fb){ + if(!widget||!widget->update)return; + widget->update(widget,fb); +} +void widget_handle_event(Widget* widget,int mouse_x,int mouse_y,int event){ + if(!widget||!widget->handle_event)return; + widget->handle_event(widget,mouse_x,mouse_y,event); +} +void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ + Widget* current=head; + while(current){ + widget_handle_event(current,mouse_x,mouse_y,event); + current=current->next; + } +} +void widget_draw_all(Widget* head,FrameBuffer* fb){ + Widget* current=head; + while(current){ + widget_draw(current,fb); + current=current->next; + } +} +void widget_update_all(Widget* head,FrameBuffer* fb){ + Widget* current=head; + while(current){ + widget_update(current,fb); + current=current->next; + } +} +void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ + Widget* current=head; + while(current){ + widget_handle_event(current,mouse_x,mouse_y,event); + current=current->next; + } +} + diff --git a/window.h b/window.h new file mode 100644 index 0000000..e173033 --- /dev/null +++ b/window.h @@ -0,0 +1,28 @@ +#ifndef WINDOW_H +#define WINDOW_H +#include "graphics.h" +#include "widget.h" +#include +typedef struct{ + int x,y,width,height; + char** title; + bool has_title_bar; + Widget* child_widgets_head; + Widget* child_widgets_tail; + struct Window* next; + struct Window* prev; + struct Window* parent; + struct Window* child; + struct Window* sibling; + +}Window; +Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar); +void window_add_widget(Window* window,Widget* widget); +void window_remove_widget(Window* window,Widget* widget); +void window_draw(Window* window,FrameBuffer* fb); +void window_update(Window* window,FrameBuffer* fb); +void window_on_click(Window* window,int mouse_x,int mouse_y,int button); +void window_on_hover(Window* window,int mouse_x,int mouse_y); +void window_on_release(Window* window,int mouse_x,int mouse_y,int button); +void window_on_move(Window* window,int mouse_x,int mouse_y); +#endif \ No newline at end of file From 140eda8ad59c16bdc9e8b1d11de5481d47eef972 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 14 Oct 2025 20:07:36 +0530 Subject: [PATCH 11/18] README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29ef9cf..50405e2 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ SimpleOS is an open-source product and we welcome contributions from the communi ## License -This product is released under the MIT License. See the LICENSE file for details. +This product is released under the Apache 2.0 License. See the LICENSE file for details. ## References From 7139335f69d939af413675f61205367a73f0c2ef Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 14 Oct 2025 20:10:17 +0530 Subject: [PATCH 12/18] README.md --- README.md | 97 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index 50405e2..c72badb 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,6 @@ # SimpleOS - A Lightweight x86 Operating System -SimpleOS is a lightweight, robust operating system for the x86 architecture, written in C and Assembly. It provides a foundational set of OS features, including protected mode, memory segmentation, and a full interrupt handling system, making it ideal for embedded applications, legacy system revival, or as a base for custom OS development. - -## Features - -- **Bootloader**: Custom 16-bit bootloader that transitions to protected mode -- **GDT (Global Descriptor Table)**: Memory segmentation with kernel/user segments -- **IDT (Interrupt Descriptor Table)**: Complete interrupt handling system with exception messages -- **VGA Text Driver**: Full-featured text output with scrolling, colors, and formatting -- **Keyboard Driver**: PS/2 keyboard support with scan code translation -- **Interactive Shell**: Command-line interface with built-in commands -- **Memory Management**: Basic protected mode memory setup -- **Interrupt Handling**: Proper CPU exception and hardware interrupt handling +SimpleOS is a lightweight, robust operating system for the x86 architecture, written in C and Assembly. It provides a foundational set of OS features, including protected mode, memory segmentation, and a full interrupt handling system, making it ideal for laptops, desktops, legacy system revival, or as a base for custom OS development. ## Architecture @@ -21,44 +10,6 @@ SimpleOS is a lightweight, robust operating system for the x86 architecture, wri 3. **Protected Mode**: Switch to 32-bit protected mode 4. **Kernel Entry**: Jump to kernel main function -### Kernel Components - -#### VGA Driver (`vga.c`, `vga.h`) -- Text mode output at 0xB8000 -- 80x25 character display -- 16-color palette support -- Automatic scrolling -- Hex/decimal number formatting - -#### GDT Manager (`gdt.c`, `gdt.h`) -- 5-entry descriptor table (null, kernel code/data, user code/data) -- Proper segment reloading -- 4GB flat memory model - -#### IDT Manager (`idt.c`, `idt.h`) -- 256 interrupt descriptors -- Exception handlers with descriptive messages -- Hardware interrupt support (PIC reprogramming) -- Assembly interrupt stubs (`interrupt.asm`) - -#### Keyboard Driver (`keyboard.c`, `keyboard.h`) -- PS/2 keyboard interrupt handler (IRQ1) -- Scan code to ASCII translation -- Shift and Caps Lock support -- Key buffer for input queuing -- Integration with shell interface - -#### Interactive Shell (`shell.c`, `shell.h`) -- Command-line interface -- Built-in commands: help, clear, about, reboot, halt -- Command history and input processing -- Backspace support and line editing - -#### Kernel Main (`kernel.c`) -- System initialization sequence -- Colorized boot messages -- Shell initialization and main loop - ## Building ### Prerequisites @@ -68,14 +19,6 @@ You need a cross-compilation toolchain for i686-elf: - `i686-elf-ld` (Linker) - `nasm` (Netwide Assembler) -### Installation on Ubuntu/Debian: -```bash -sudo apt-get install build-essential nasm qemu-system-x86 -# For the cross-compiler, you can build it from source. -# A good guide can be found here: https://wiki.osdev.org/GCC_Cross-Compiler -# Alternatively, some package managers might have pre-built toolchains. -``` - ### Installation on Windows: 1. Install MSYS2 2. Install cross-compilation tools: @@ -109,42 +52,6 @@ bochs -f bochsrc.txt 2. Mount `build/os.img` as floppy image 3. Boot from floppy -## Using the Shell - -Once the system boots, you'll see the SimpleOS shell prompt: - -``` -SimpleOS> -``` - -The agent will process your request and respond accordingly. - -### Example Interactions -- `> what time is it?` -- `> create a new file named notes.txt` -- `> tell me about the CPU` -- `> reboot the machine in 5 minutes` - -## File Structure - -``` -SimpleOS/ -├── boot/ -│ └── boot.asm # 16-bit bootloader -├── kernel/ -│ ├── kernel.c # Kernel main and initialization -│ ├── gdt.c/.h # Global Descriptor Table -│ ├── idt.c/.h # Interrupt Descriptor Table -│ ├── vga.c/.h # VGA text driver -│ ├── keyboard.c/.h # PS/2 keyboard driver -│ ├── agent.c/.h # The core AI agent logic -│ └── interrupt.asm # Assembly interrupt handlers -├── build/ # Build output (auto-generated) -├── Makefile # Build configuration -├── linker.ld # Linker script -└── README.md # This file -``` - ## Technical Details ### Memory Layout @@ -178,7 +85,7 @@ Future development is focused on expanding the kernel's capabilities. Key areas ## Contributing -SimpleOS is an open-source product and we welcome contributions from the community. If you are interested in contributing, please feel free to fork the repository, make your changes, and submit a pull request. We are actively looking for improvements in drivers, memory management, and performance optimizations. +SimpleOS is an open-source product and I welcome contributions from the community. If you are interested in contributing, please feel free to fork the repository, make your changes, and submit a pull request. I am actively looking for improvements in drivers, memory management, and performance optimizations. ## License From cbf0e29edb4ba484658cc3ba2af417aa6cec3fa3 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Sun, 30 Nov 2025 17:49:59 +0530 Subject: [PATCH 13/18] Add files via upload --- cursor.c | 82 +++++++++++++++++++++++++++++++ cursor.h | 8 +++ graphics.h | 1 + kernel.c | 41 ++++++++++++++-- keyboard.c | 2 - mouse.c | 91 +++++++++++++++++++++++++++++++++++ mouse.h | 17 +++++++ paging.h | 20 ++++---- pmm.h | 15 +++--- window.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++- window.h | 5 ++ 11 files changed, 397 insertions(+), 24 deletions(-) create mode 100644 cursor.c create mode 100644 cursor.h create mode 100644 mouse.c create mode 100644 mouse.h diff --git a/cursor.c b/cursor.c new file mode 100644 index 0000000..6dce54e --- /dev/null +++ b/cursor.c @@ -0,0 +1,82 @@ +#include "cursor.h" +#define CURSOR_WIDTH 16 +#define CURSOR_HEIGHT 16 +static const uint8_t cursor_bitmap[CURSOR_HEIGHT][CURSOR_WIDTH / 8] = { + {0b00000000, 0b00000000}, + {0b00000000, 0b10000000}, + {0b00000001, 0b11000000}, + {0b00000011, 0b11100000}, + {0b00000111, 0b11110000}, + {0b00001111, 0b11111000}, + {0b00011111, 0b11111100}, + {0b00111111, 0b11111110}, + {0b01111111, 0b11111111}, + {0b00111111, 0b11111110}, + {0b00011111, 0b11111100}, + {0b00001111, 0b11111000}, + {0b00000111, 0b11110000}, + {0b00000011, 0b11100000}, + {0b00000001, 0b11000000}, + {0b00000000, 0b10000000} +}; +static uint32_t cursor_bg_buffer[CURSOR_HEIGHT*CURSOR_WIDTH]; +static uint32_t cursor_fg_buffer[CURSOR_HEIGHT*CURSOR_WIDTH]; +static int prev_x = -1, prev_y = -1; +static int visible = 0; +void cursor_init(void) { + // Initialization if needed + prev_x = -1; + prev_y = -1; + visible = 0; +} +void cursor_draw(FrameBuffer* fb, int x, int y) { + for (int cy = 0; cy < CURSOR_HEIGHT; cy++) { + for (int cx = 0; cx < CURSOR_WIDTH; cx++) { + int byte_index = cx / 8; + int bit_index = 7 - (cx % 8); + uint8_t mask = 1 << bit_index; + int fb_x = x + cx; + int fb_y = y + cy; + if (fb_x < 0 || fb_x >= fb->width || fb_y < 0 || fb_y >= fb->height) continue; + uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->base_address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); + if (cursor_bitmap[cy][byte_index] & mask) { + cursor_fg_buffer[cy * CURSOR_WIDTH + cx] = *fb_pixel; + *fb_pixel = 0xFFFFFFFF; // White color for cursor + } else { + cursor_bg_buffer[cy * CURSOR_WIDTH + cx] = *fb_pixel; + *fb_pixel = 0x00000000; // Black color for cursor background + } + } + } + visible = 1; + prev_x = x; + prev_y = y; +} +void cursor_hide(void) { + if (!visible) return; + visible = 0; +} +void cursor_update(FrameBuffer* fb, int x, int y) { + if (visible) { + for (int cy = 0; cy < CURSOR_HEIGHT; cy++) { + for (int cx = 0; cx < CURSOR_WIDTH; cx++) { + int fb_x = prev_x + cx; + int fb_y = prev_y + cy; + if (fb_x < 0 || fb_x >= fb->width || fb_y < 0 || fb_y >= fb->height) continue; + uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->base_address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); + if (cursor_bitmap[cy][cx / 8] & (1 << (7 - (cx % 8)))) { + *fb_pixel = cursor_fg_buffer[cy * CURSOR_WIDTH + cx]; + } else { + *fb_pixel = cursor_bg_buffer[cy * CURSOR_WIDTH + cx]; + } + } + } + } + cursor_draw(fb, x, y); +} +#undef CURSOR_WIDTH +#undef CURSOR_HEIGHT +#undef cursor_bitmap +#undef CURSOR_BG_BUFFER +#undef CURSOR_FG_BUFFER +#undef CURSOR_VISIBLE \ No newline at end of file diff --git a/cursor.h b/cursor.h new file mode 100644 index 0000000..a694c71 --- /dev/null +++ b/cursor.h @@ -0,0 +1,8 @@ +#ifndef CURSOR_H +#define CURSOR_H +#include +#include "graphics.h" +void cursor_init(void); +void cursor_update(FrameBuffer*fb,int x,int y); +void cursor_draw(FrameBuffer*fb,int x,int y); +#endif // CURSOR_H \ No newline at end of file diff --git a/graphics.h b/graphics.h index 05624fe..c339dac 100644 --- a/graphics.h +++ b/graphics.h @@ -44,6 +44,7 @@ void clear_screen(FrameBuffer* fb, uint32_t color); void put_pixel(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t color); void draw_line(FrameBuffer* fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t color); void draw_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color); +void fill_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color); void draw_circle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t radius, uint32_t color); void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, uint32_t x, uint32_t y, uint32_t color); void draw_char(FrameBuffer* fb, Font* font, char c, uint32_t x, uint32_t y, uint32_t color); diff --git a/kernel.c b/kernel.c index d53a123..81f61f7 100644 --- a/kernel.c +++ b/kernel.c @@ -17,6 +17,8 @@ #include "task.h" #include "syscall.h" #include "window.h" +#include "mouse.h" +#include "cursor.h" void counter_task(){ int i=0; while(1){ @@ -32,16 +34,13 @@ void on_my_button_click(){ if(!data)return; data->bg_color=data->press_color; data->border_color=data->press_border; - //vga_print_string("Button clicked!\n"); } void on_my_button_release(){ if(!g_widget_font)return; ButtonData* data=(ButtonData*)widget_list_head->data; if(!data)return; data->bg_color=data->base_color; - data->border_color=data->border_color; - //vga_print_string("Button released!\n"); -} + data->border_color=data->border_color;} typedef struct { uint16_t attributes; uint8_t window_a, window_b; @@ -53,7 +52,6 @@ typedef struct { uint8_t chars_x, chars_y, planes, bitsPerPixel, banks; uint8_t memory_model, bank_size, image_pages; uint8_t reserved0; - // ... other fields might follow uint32_t physbase; } __attribute__((packed)) vbe_mode_info_t; @@ -75,6 +73,8 @@ void kernel_main(void) { timer_install(); rtl8139_init(); tasking_install(); + mouse_install(); + cursor_init(); create_task("shell",shell_init); create_task("counter",counter_task); uint32_t free_mem = pmm_get_free_memory(); @@ -132,7 +132,38 @@ void kernel_main(void) { init_widget_system(); widget_set_font(&my_font); //Scheduler takes over, chillax!! + + #define CURSOR_TRAIL_LENGTH 8 + struct { int32_t x, y; } cursor_history[CURSOR_TRAIL_LENGTH] = {0}; + int history_index = 0; + + uint8_t last_buttons = 0; + int32_t last_x = -1, last_y = -1; + while(1) { + window_manager_handle_mouse(&window_list_head, &window_list_tail, mouse_x, mouse_y, mouse_buttons, last_buttons); + wm_process_mouse(mouse_x, mouse_y, mouse_buttons, last_buttons); + cursor_update(&fb, mouse_x, mouse_y); + widget_update_all(widget_list_head, &fb); + window_update_all(window_list_head, &fb); + if(mouse_buttons != last_buttons || mouse_x != last_x || mouse_y != last_y) { + window_draw_all(window_list_head, &fb); + last_x = mouse_x; + last_y = mouse_y; + cursor_history[history_index].x = mouse_x; + cursor_history[history_index].y = mouse_y; + history_index = (history_index + 1) % CURSOR_TRAIL_LENGTH; + for (int i = 0; i < CURSOR_TRAIL_LENGTH; i++) { + int current_idx = (history_index - 1 - i + CURSOR_TRAIL_LENGTH) % CURSOR_TRAIL_LENGTH; + int32_t x = cursor_history[current_idx].x; + int32_t y = cursor_history[current_idx].y; + // Fade the tail from white to gray + uint8_t intensity = 255 - (i * (255 / CURSOR_TRAIL_LENGTH)); + uint32_t color = (intensity << 16) | (intensity << 8) | intensity; + fb_set_pixel(&fb, x, y, color); + } + last_buttons = mouse_buttons; + } asm volatile("hlt"); } } diff --git a/keyboard.c b/keyboard.c index 49b5802..e52084b 100644 --- a/keyboard.c +++ b/keyboard.c @@ -71,8 +71,6 @@ void keyboard_handler(registers_t *r) { } if (ch != 0) { - shell_handle_input(ch); - int next_end = (buffer_end + 1) % 256; if (next_end != buffer_start) { key_buffer[buffer_end] = ch; diff --git a/mouse.c b/mouse.c new file mode 100644 index 0000000..1fb2157 --- /dev/null +++ b/mouse.c @@ -0,0 +1,91 @@ +#include "mouse.h" +#include "vga.h" +#include "ports.h" +#include "isr.h" +#include "idt.h" +#define MOUSE_DATA_PORT 0x60 +#define MOUSE_STATUS_PORT 0x64 +#define MOUSE_COMMAND_PORT 0x64 +#define MOUSE_IRQ 12 +volatile int32_t mouse_x = 400; +volatile int32_t mouse_y = 300; +volatile uint8_t mouse_buttons = 0; +uint8_t mouse_cycle = 0; +int8_t mouse_byte[3]; +mouse_packet_t mouse_packet; +static void mouse_handler(registers_t *regs); +static void mouse_wait(uint8_t a_type) { + uint32_t _time_out = 100000; + if (a_type == 0) { + while (_time_out--) { + if ((inb(MOUSE_STATUS_PORT) & 1) == 1) { + return; + } + } + return; + } else { + while (_time_out--) { + if ((inb(MOUSE_STATUS_PORT) & 2) == 0) { + return; + } + } + return; + } +} +static void mouse_write(uint8_t data) { + mouse_wait(0); + outb(MOUSE_DATA_PORT, data); + mouse_wait(1); +} +static uint8_t mouse_read() { + mouse_wait(0); + return inb(MOUSE_DATA_PORT); +} + +void mouse_install(void) { + // Enable the auxiliary mouse device + outb(MOUSE_COMMAND_PORT, 0xA8); + // Enable the mouse IRQ + outb(MOUSE_COMMAND_PORT, 0x20); + uint8_t status = inb(MOUSE_DATA_PORT); + status |= 2; // Enable IRQ12 + outb(MOUSE_COMMAND_PORT, 0x60); + outb(MOUSE_DATA_PORT, status); + // Tell the mouse to use default settings + outb(MOUSE_COMMAND_PORT, 0xD4); + outb(MOUSE_DATA_PORT, 0xF6); + inb(MOUSE_DATA_PORT); // Acknowledge + // Enable the mouse + outb(MOUSE_COMMAND_PORT, 0xD4); + outb(MOUSE_DATA_PORT, 0xF4); + inb(MOUSE_DATA_PORT); // Acknowledge + // Register the mouse handler + register_interrupt_handler(MOUSE_IRQ + 32, mouse_handler); +} +void mouse_handler(registers_t *regs) { + static uint8_t packet_byte_index = 0; + static mouse_packet_t packet; + uint8_t status = inb(MOUSE_STATUS_PORT); + if (status & 0x20) { + uint8_t data = inb(MOUSE_DATA_PORT); + switch (packet_byte_index) { + case 0: + packet.flags = data; + break; + case 1: + packet.x_delta = (int8_t)data; + break; + case 2: + packet.y_delta = (int8_t)data; + break; + } + packet_byte_index++; + if (packet_byte_index == 3) { + mouse_packet = packet; + mouse_x += packet.x_delta; + mouse_y -= packet.y_delta; // Invert Y axis + mouse_buttons = packet.flags & 0x07; // Update button states + packet_byte_index = 0; // Reset for next packet + } + } +} \ No newline at end of file diff --git a/mouse.h b/mouse.h new file mode 100644 index 0000000..c357396 --- /dev/null +++ b/mouse.h @@ -0,0 +1,17 @@ +#ifndef MOUSE_H +#define MOUSE_H +#include +#include "idt.h" +typedef struct { + uint8_t flags; + int8_t x_delta; + int8_t y_delta; + +} __attribute__((packed)) mouse_packet_t; +//Global mouse states +extern mouse_packet_t mouse_packet; +extern volatile int32_t mouse_x; +extern volatile int32_t mouse_y; +extern volatile uint8_t mouse_buttons; //Bit 0: left, Bit 1 : Right, Bit 2: Middle +void mouse_install(void); +#endif \ No newline at end of file diff --git a/paging.h b/paging.h index 3c84d11..5d6857b 100644 --- a/paging.h +++ b/paging.h @@ -10,15 +10,17 @@ extern pt_entry_t page_directory[1024]; extern pt_entry_t fpage_table[1024]; //Below is for defining page table entry typedef struct pt_entry{ - uint32_t present:1; - uint32_t rw:1; - uint32_t user_supervisor:1; - uint32_t pwt:1; // Page Write-Through - uint32_t pcd:1; // Page Cache Disable - uint32_t accessed:1; - uint32_t dirty:1; - uint32_t reserved:5; // Reserved bits - uint32_t frame:20; // Frame address + uint32_t present:1; // Bit 0: Present + uint32_t rw:1; // Bit 1: Read/Write + uint32_t user_supervisor:1; // Bit 2: User/Supervisor + uint32_t pwt:1; // Bit 3: Page Write-Through + uint32_t pcd:1; // Bit 4: Page Cache Disable + uint32_t accessed:1; // Bit 5: Accessed + uint32_t dirty:1; // Bit 6: Dirty + uint32_t pat:1; // Bit 7: Page Attribute Table + uint32_t global:1; // Bit 8: Global + uint32_t avail:3; // Bits 9-11: Available for software use + uint32_t frame:20; // Bits 12-31: Frame address (shifted right 12 bits) } pt_entry_t; // Function declarations diff --git a/pmm.h b/pmm.h index 1c88f91..ec7e5d9 100644 --- a/pmm.h +++ b/pmm.h @@ -1,15 +1,18 @@ #ifndef PMM_H #define PMM_H #include -#define PAGE_STATE_FREE 0x01 -#define PAGE_STATE_USED 0x02 -#define PAGE_STATE_RESERVED 0x04 -#define PAGE_STATE_KERNEL 0x08 +#include + +#define PAGE_SIZE 4096 + +typedef enum { PAGE_STATE_FREE=0, PAGE_STATE_USED=1, PAGE_STATE_RESERVED=2 } page_state_t; + typedef struct page_frame { - uint8_t state; - uint8_t order; struct page_frame* next; struct page_frame* prev; + uint8_t order; + page_state_t state; + // ... other metadata } page_frame_t; void pmm_init(uint32_t memory_end); diff --git a/window.c b/window.c index 134317d..2903574 100644 --- a/window.c +++ b/window.c @@ -4,8 +4,17 @@ #define WINDOW_BG_COLOR 0xECECEC #define TITLE_BAR_COLOR 0x2C2C2C #define TITLE_TEXT_COLOR 0xFFFFFF -#define TITLE_BAR_HEIGHT 25 +#define TITLE_BAR_HEIGHT 25 +#define CLOSE_BUTTON_WIDTH 18 +#define CLOSE_BUTTON_HEIGHT 18 +#define CLOSE_BUTTON_MARGIN 4 +#define CLOSE_BUTTON_BG_COLOR 0xFF0000 // Red +#define CLOSE_BUTTON_HOVER_BG_COLOR 0xFF4444 // Brighter Red for hover +#define CLOSE_BUTTON_X_COLOR 0xFFFFFF // White extern Font* g_widget_font; +extern Window* window_list_head; +extern Window* window_list_tail; +static Widget* last_hivered_widget = NULL; Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar){ Window* window=(Window*)malloc(sizeof(Window)); if(!window)return NULL; @@ -22,6 +31,7 @@ Window* create_window(int x,int y,int width,int height,char** title,bool has_tit window->parent=NULL; window->child=NULL; window->sibling=NULL; + window->close_button_hovered = false; return window; } void window_add_widget(Window* window,Widget* widget){ @@ -95,6 +105,21 @@ void window_draw(Window* window,FrameBuffer* fb){ int text_y=window->y+(TITLE_BAR_HEIGHT-text_height)/2; draw_string(fb,text_x,text_y,*window->title,TITLE_TEXT_COLOR,g_widget_font); } + + // Draw close button + int btn_x = window->x + window->width - CLOSE_BUTTON_WIDTH - CLOSE_BUTTON_MARGIN; + int btn_y = window->y + (TITLE_BAR_HEIGHT - CLOSE_BUTTON_HEIGHT) / 2; + uint32_t btn_color = window->close_button_hovered ? CLOSE_BUTTON_HOVER_BG_COLOR : CLOSE_BUTTON_BG_COLOR; + fill_rectangle(fb, btn_x, btn_y, CLOSE_BUTTON_WIDTH, CLOSE_BUTTON_HEIGHT, btn_color); + + // Draw 'X' on the button + int x_margin = 4; + draw_line(fb, btn_x + x_margin, btn_y + x_margin, + btn_x + CLOSE_BUTTON_WIDTH - x_margin - 1, btn_y + CLOSE_BUTTON_HEIGHT - x_margin - 1, + CLOSE_BUTTON_X_COLOR); + draw_line(fb, btn_x + x_margin, btn_y + CLOSE_BUTTON_HEIGHT - x_margin - 1, + btn_x + CLOSE_BUTTON_WIDTH - x_margin - 1, btn_y + x_margin, + CLOSE_BUTTON_X_COLOR); } // Draw child widgets widget_draw_all(window->child_widgets_head,fb); @@ -130,6 +155,114 @@ void widget_draw_all(Widget* head,FrameBuffer* fb){ current=current->next; } } + +void window_destroy(Window** head, Window** tail, Window* win_to_destroy) { + if (!win_to_destroy) return; + + // Unlink from the list + if (win_to_destroy->prev) { + win_to_destroy->prev->next = win_to_destroy->next; + } else { // It's the head + *head = win_to_destroy->next; + } + + if (win_to_destroy->next) { + win_to_destroy->next->prev = win_to_destroy->prev; + } else { // It's the tail + *tail = win_to_destroy->prev; + } + + // Free associated widgets and the window itself + window_free_widgets(win_to_destroy); + free(win_to_destroy); +} + + +void window_bring_to_front(Window** head, Window** tail, Window* win) { + if (!win || *tail == win) { + return; // Already at the front or invalid window + } + + // Unlink from current position + if (win->prev) { + win->prev->next = win->next; + } else { // It's the head + *head = win->next; + } + + if (win->next) { + win->next->prev = win->prev; + } else { // It's the tail - this case should not happen if *tail != win + *tail = win->prev; + } + + // Add to the tail (front of the drawing order) + (*tail)->next = win; + win->prev = *tail; + win->next = NULL; + *tail = win; +} + +// State for window dragging, kept static within this file +static Window* dragged_window = NULL; +static int32_t drag_offset_x = 0; +static int32_t drag_offset_y = 0; + +void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, int32_t mouse_y, uint8_t mouse_buttons, uint8_t last_buttons) { + + Window* top_win = *tail; + if (top_win) { + int btn_x = top_win->x + top_win->width - CLOSE_BUTTON_WIDTH - CLOSE_BUTTON_MARGIN; + int btn_y = top_win->y + (TITLE_BAR_HEIGHT - CLOSE_BUTTON_HEIGHT) / 2; + + if (mouse_x >= btn_x && mouse_x < btn_x + CLOSE_BUTTON_WIDTH && + mouse_y >= btn_y && mouse_y < btn_y + CLOSE_BUTTON_HEIGHT) { + top_win->close_button_hovered = true; + } else { + top_win->close_button_hovered = false; + } + } + + + // 1. Mouse button pressed + if ((mouse_buttons & 1) && !(last_buttons & 1)) { + // Iterate from top window (tail) to bottom to find which one was clicked + Window* win = *tail; + if (win) { // Only proceed if there is at least one window + // Check for close button click first + int btn_x = win->x + win->width - CLOSE_BUTTON_WIDTH - CLOSE_BUTTON_MARGIN; + int btn_y = win->y + (TITLE_BAR_HEIGHT - CLOSE_BUTTON_HEIGHT) / 2; + if (mouse_x >= btn_x && mouse_x < btn_x + CLOSE_BUTTON_WIDTH && + mouse_y >= btn_y && mouse_y < btn_y + CLOSE_BUTTON_HEIGHT) { + + window_destroy(head, tail, win); + // Don't proceed to drag checks + + } else if (mouse_x >= win->x && mouse_x < win->x + win->width && + mouse_y >= win->y && mouse_y < win->y + TITLE_BAR_HEIGHT) { + // It's a drag operation + dragged_window = win; + drag_offset_x = mouse_x - win->x; + drag_offset_y = mouse_y - win->y; + + window_bring_to_front(head, tail, win); + } else { + // Click was outside the top window's title bar, maybe handle widget clicks here in the future + } + } + } + + // 2. Mouse button released + if (!(mouse_buttons & 1) && (last_buttons & 1)) { + dragged_window = NULL; + } + + // 3. Mouse moved while dragging + if (dragged_window != NULL) { + dragged_window->x = mouse_x - drag_offset_x; + dragged_window->y = mouse_y - drag_offset_y; + } +} void widget_draw(Widget* widget,FrameBuffer* fb){ if(!widget||!widget->draw)return; widget->draw(widget,fb); @@ -170,4 +303,6 @@ void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ current=current->next; } } - +void wm_process_mouse(int mouse_x,int mouse_y,uint8_t mouse_buttons,uint8_t last_buttons){ + window_manager_handle_mouse(&window_list_head,&window_list_tail,mouse_x,mouse_y,mouse_buttons,last_buttons); +} diff --git a/window.h b/window.h index e173033..e281e84 100644 --- a/window.h +++ b/window.h @@ -14,6 +14,7 @@ typedef struct{ struct Window* parent; struct Window* child; struct Window* sibling; + bool close_button_hovered; }Window; Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar); @@ -25,4 +26,8 @@ void window_on_click(Window* window,int mouse_x,int mouse_y,int button); void window_on_hover(Window* window,int mouse_x,int mouse_y); void window_on_release(Window* window,int mouse_x,int mouse_y,int button); void window_on_move(Window* window,int mouse_x,int mouse_y); +void wm_process_mouse(int mouse_x,int mouse_y,uint8_t mouse_buttons,uint8_t last_buttons); +void window_destroy(Window** head, Window** tail, Window* win_to_destroy); +void window_bring_to_front(Window** head, Window** tail, Window* win); +void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, int32_t mouse_y, uint8_t mouse_buttons, uint8_t last_buttons); #endif \ No newline at end of file From dfe7da09d9abf21650ea3a75c6cf3b7f7b0cecd9 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Tue, 9 Dec 2025 22:36:01 +0530 Subject: [PATCH 14/18] Add files via upload --- Makefile | 47 +++++++++ README.md | 291 +++++++++++++++++++++++++++++++++------------------ boot.asm | 113 +++++++++++++++----- boot.bin | Bin 0 -> 512 bytes cursor.c | 13 ++- cursor.o | Bin 0 -> 2179 bytes dirty_rect.c | 52 +++++++++ dirty_rect.h | 28 +++++ dirty_rect.o | Bin 0 -> 1570 bytes heap.c | 121 +++++++++++++++++++++ heap.h | 11 ++ kernel.c | 71 +++++++++---- keyboard.c | 4 + linker.ld | 27 +++++ sync.h | 35 +++++++ widget.h | 8 ++ window.c | 124 ++++++++++++---------- window.h | 13 +-- 18 files changed, 749 insertions(+), 209 deletions(-) create mode 100644 Makefile create mode 100644 boot.bin create mode 100644 cursor.o create mode 100644 dirty_rect.c create mode 100644 dirty_rect.h create mode 100644 dirty_rect.o create mode 100644 heap.c create mode 100644 heap.h create mode 100644 linker.ld create mode 100644 sync.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fba4187 --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +# SimpleOS Flat Makefile + +# Tool definitions +CC = i686-w64-mingw32-gcc +LD = i686-w64-mingw32-ld +OBJCOPY = i686-w64-mingw32-objcopy +NASM = nasm + +# Flags: 32-bit, no standard libs, include current directory +CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. + +# Auto-detect all .c files in the current folder +C_SOURCES = $(wildcard *.c) +# Create a list of .o files to build +OBJ = $(C_SOURCES:.c=.o) + +# Default target +all: os.img + +# 1. Create the Disk Image (Boot + Kernel) +os.img: boot.bin kernel.bin + cat boot.bin kernel.bin > os.img + +# 2. Compile the Bootloader (Flat Binary) +boot.bin: boot.asm + $(NASM) -f bin boot.asm -o boot.bin + +# 3. Compile the Kernel (Binary extraction) +kernel.bin: kernel.tmp + $(OBJCOPY) -O binary kernel.tmp kernel.bin + +# 4. Link the Kernel (at 1MB) +# Note: interrupt.o must be linked! +kernel.tmp: $(OBJ) interrupt.o + $(LD) -Ttext 0x100000 -o kernel.tmp $(OBJ) interrupt.o + +# 5. Compile Assembly Stub (Interrupts) +interrupt.o: interrupt.asm + $(NASM) -f win32 interrupt.asm -o interrupt.o + +# 6. Compile C Files +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +# Clean +clean: + rm -f *.o *.bin *.tmp os.img \ No newline at end of file diff --git a/README.md b/README.md index c72badb..703c939 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,192 @@ -# SimpleOS - A Lightweight x86 Operating System - -SimpleOS is a lightweight, robust operating system for the x86 architecture, written in C and Assembly. It provides a foundational set of OS features, including protected mode, memory segmentation, and a full interrupt handling system, making it ideal for laptops, desktops, legacy system revival, or as a base for custom OS development. - -## Architecture - -### Boot Process -1. **Real Mode Boot**: 16-bit bootloader loads from sector 0 -2. **A20 Line**: Enable extended memory access -3. **Protected Mode**: Switch to 32-bit protected mode -4. **Kernel Entry**: Jump to kernel main function - -## Building - -### Prerequisites - -You need a cross-compilation toolchain for i686-elf: -- `i686-elf-gcc` (C compiler) -- `i686-elf-ld` (Linker) -- `nasm` (Netwide Assembler) - -### Installation on Windows: -1. Install MSYS2 -2. Install cross-compilation tools: -```bash -pacman -S mingw-w64-i686-gcc nasm -``` - -### Compilation -```bash -make all # Build OS image -make clean # Remove build files -make qemu # Run with QEMU (if installed) -make bochs # Run with Bochs (if installed) -make help # Show available targets -``` - -## Running - -### QEMU (Recommended) -```bash -qemu-system-i386 -fda build/os.img -``` - -### Bochs -```bash -bochs -f bochsrc.txt -``` - -### VirtualBox/VMware -1. Create new VM with floppy disk -2. Mount `build/os.img` as floppy image -3. Boot from floppy - -## Technical Details - -### Memory Layout -- **0x00007C00**: Bootloader load address -- **0x00100000**: Kernel load address (1MB) -- **0x000B8000**: VGA text buffer -- **0x00090000**: Stack pointer - -### Interrupts -- **ISR 0-31**: CPU exceptions (division error, page fault, etc.) -- **IRQ 0-15**: Hardware interrupts (timer, keyboard, etc.) -- **PIC Remapping**: Master PIC (0x20-0x27), Slave PIC (0x28-0x2F) - -### Color Codes (VGA) -- 0=Black, 1=Blue, 2=Green, 3=Cyan, 4=Red, 5=Magenta -- 6=Brown, 7=Light Grey, 8=Dark Grey, 9=Light Blue -- 10=Light Green, 11=Light Cyan, 12=Light Red -- 13=Light Magenta, 14=Light Brown, 15=White - -## Roadmap - -Future development is focused on expanding the kernel's capabilities. Key areas on our roadmap include: - -- **Agent Tooling**: Expanding the set of kernel functions (tools) the LLM agent can use. -- **Long-Term Memory**: Implementing a file system to give the agent persistent memory. -- **Multitasking**: Allowing the agent to manage and execute multiple background processes. - -### Debugging -- Connect GDB: `gdb -ex "target remote :1234"` -- Enable QEMU monitor: Add `-monitor stdio` - -## Contributing - -SimpleOS is an open-source product and I welcome contributions from the community. If you are interested in contributing, please feel free to fork the repository, make your changes, and submit a pull request. I am actively looking for improvements in drivers, memory management, and performance optimizations. - -## License - -This product is released under the Apache 2.0 License. See the LICENSE file for details. - -## References - -- [OSDev Wiki](https://wiki.osdev.org/) - Comprehensive OS development resource -- [Intel 80386 Manual](https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html) -- [Bran's Kernel Development Tutorial](http://www.osdever.net/bkerndev/Docs/title.htm) -- [JamesM's Kernel Development Tutorials](https://web.archive.org/web/20160412174753/http://www.jamesmolloy.co.uk/tutorial_html/index.html) +# SimpleOS - A Lightweight x86 Operating System + +SimpleOS is a lightweight, robust operating system for the x86 architecture, written in C and Assembly. It provides a foundational set of OS features, including protected mode, memory segmentation, and a full interrupt handling system, making it ideal for embedded applications, legacy system revival, or as a base for custom OS development. + +## Features + +- **Bootloader**: Custom 16-bit bootloader that transitions to protected mode +- **GDT (Global Descriptor Table)**: Memory segmentation with kernel/user segments +- **IDT (Interrupt Descriptor Table)**: Complete interrupt handling system with exception messages +- **VGA Text Driver**: Full-featured text output with scrolling, colors, and formatting +- **Keyboard Driver**: PS/2 keyboard support with scan code translation +- **Interactive Shell**: Command-line interface with built-in commands +- **Memory Management**: Basic protected mode memory setup +- **Interrupt Handling**: Proper CPU exception and hardware interrupt handling + +## Architecture + +### Boot Process +1. **Real Mode Boot**: 16-bit bootloader loads from sector 0 +2. **A20 Line**: Enable extended memory access +3. **Protected Mode**: Switch to 32-bit protected mode +4. **Kernel Entry**: Jump to kernel main function + +### Kernel Components + +#### VGA Driver (`vga.c`, `vga.h`) +- Text mode output at 0xB8000 +- 80x25 character display +- 16-color palette support +- Automatic scrolling +- Hex/decimal number formatting + +#### GDT Manager (`gdt.c`, `gdt.h`) +- 5-entry descriptor table (null, kernel code/data, user code/data) +- Proper segment reloading +- 4GB flat memory model + +#### IDT Manager (`idt.c`, `idt.h`) +- 256 interrupt descriptors +- Exception handlers with descriptive messages +- Hardware interrupt support (PIC reprogramming) +- Assembly interrupt stubs (`interrupt.asm`) + +#### Keyboard Driver (`keyboard.c`, `keyboard.h`) +- PS/2 keyboard interrupt handler (IRQ1) +- Scan code to ASCII translation +- Shift and Caps Lock support +- Key buffer for input queuing +- Integration with shell interface + +#### Interactive Shell (`shell.c`, `shell.h`) +- Command-line interface +- Built-in commands: help, clear, about, reboot, halt +- Command history and input processing +- Backspace support and line editing + +#### Kernel Main (`kernel.c`) +- System initialization sequence +- Colorized boot messages +- Shell initialization and main loop + +## Building + +### Prerequisites + +You need a cross-compilation toolchain for i686-elf: +- `i686-elf-gcc` (C compiler) +- `i686-elf-ld` (Linker) +- `nasm` (Netwide Assembler) + +### Installation on Ubuntu/Debian: +```bash +sudo apt-get install build-essential nasm qemu-system-x86 +# For the cross-compiler, you can build it from source. +# A good guide can be found here: https://wiki.osdev.org/GCC_Cross-Compiler +# Alternatively, some package managers might have pre-built toolchains. +``` + +### Installation on Windows: +1. Install MSYS2 +2. Install cross-compilation tools: +```bash +pacman -S mingw-w64-i686-gcc nasm +``` + +### Compilation +```bash +make all # Build OS image +make clean # Remove build files +make qemu # Run with QEMU (if installed) +make bochs # Run with Bochs (if installed) +make help # Show available targets +``` + +## Running + +### QEMU (Recommended) +```bash +qemu-system-i386 -fda build/os.img +``` + +### Bochs +```bash +bochs -f bochsrc.txt +``` + +### VirtualBox/VMware +1. Create new VM with floppy disk +2. Mount `build/os.img` as floppy image +3. Boot from floppy + +## Using the Shell + +Once the system boots, you'll see the SimpleOS shell prompt: + +``` +SimpleOS> +``` + +The agent will process your request and respond accordingly. + +### Example Interactions +- `> what time is it?` +- `> create a new file named notes.txt` +- `> tell me about the CPU` +- `> reboot the machine in 5 minutes` + +## File Structure + +``` +SimpleOS/ +├── boot/ +│ └── boot.asm # 16-bit bootloader +├── kernel/ +│ ├── kernel.c # Kernel main and initialization +│ ├── gdt.c/.h # Global Descriptor Table +│ ├── idt.c/.h # Interrupt Descriptor Table +│ ├── vga.c/.h # VGA text driver +│ ├── keyboard.c/.h # PS/2 keyboard driver +│ ├── agent.c/.h # The core AI agent logic +│ └── interrupt.asm # Assembly interrupt handlers +├── build/ # Build output (auto-generated) +├── Makefile # Build configuration +├── linker.ld # Linker script +└── README.md # This file +``` + +## Technical Details + +### Memory Layout +- **0x00007C00**: Bootloader load address +- **0x00100000**: Kernel load address (1MB) +- **0x000B8000**: VGA text buffer +- **0x00090000**: Stack pointer + +### Interrupts +- **ISR 0-31**: CPU exceptions (division error, page fault, etc.) +- **IRQ 0-15**: Hardware interrupts (timer, keyboard, etc.) +- **PIC Remapping**: Master PIC (0x20-0x27), Slave PIC (0x28-0x2F) + +### Color Codes (VGA) +- 0=Black, 1=Blue, 2=Green, 3=Cyan, 4=Red, 5=Magenta +- 6=Brown, 7=Light Grey, 8=Dark Grey, 9=Light Blue +- 10=Light Green, 11=Light Cyan, 12=Light Red +- 13=Light Magenta, 14=Light Brown, 15=White + +## Roadmap + +Future development is focused on expanding the kernel's capabilities. Key areas on our roadmap include: + +- **Agent Tooling**: Expanding the set of kernel functions (tools) the LLM agent can use. +- **Long-Term Memory**: Implementing a file system to give the agent persistent memory. +- **Multitasking**: Allowing the agent to manage and execute multiple background processes. + +### Debugging +- Connect GDB: `gdb -ex "target remote :1234"` +- Enable QEMU monitor: Add `-monitor stdio` + +## Contributing + +SimpleOS is an open-source product and we welcome contributions from the community. If you are interested in contributing, please feel free to fork the repository, make your changes, and submit a pull request. We are actively looking for improvements in drivers, memory management, and performance optimizations. + +## License + +This product is released under the MIT License. See the LICENSE file for details. + +## References + +- [OSDev Wiki](https://wiki.osdev.org/) - Comprehensive OS development resource +- [Intel 80386 Manual](https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html) +- [Bran's Kernel Development Tutorial](http://www.osdever.net/bkerndev/Docs/title.htm) +- [JamesM's Kernel Development Tutorials](https://web.archive.org/web/20160412174753/http://www.jamesmolloy.co.uk/tutorial_html/index.html) \ No newline at end of file diff --git a/boot.asm b/boot.asm index dabd58f..f58497c 100644 --- a/boot.asm +++ b/boot.asm @@ -1,5 +1,11 @@ bits 16 org 0x7c00 + +; --- Memory Definitions (NOT File Space) --- +VBE_INFO_BLOCK equ 0x9000 +MODE_INFO_BLOCK equ 0x9200 + +; --- Constants --- VBE_MAGIC equ 0x4F VBE_GET_INFO equ 0x00 VBE_GET_MODE_INFO equ 0x01 @@ -7,59 +13,111 @@ VBE_SET_MODE equ 0x02 TARGET_WIDTH equ 1280 TARGET_HEIGHT equ 720 TARGET_BPP equ 32 -;extern kernel_main + +; Kernel placement +KERNEL_TEMP_ADDR equ 0x1000 ; Segment 0x1000 (Physical 0x10000) +KERNEL_TARGET_ADDR equ 0x100000 ; 1MB +SECTORS_TO_READ equ 60 ; Read 30KB start: - cli - cld + jmp 0:init_segments ; Far jump to normalize CS + +init_segments: xor ax, ax mov ds, ax mov es, ax mov ss, ax mov sp, 0x7c00 + + mov [boot_drive], dl ; Save the boot drive number provided by BIOS + + ; 1. Load Kernel from Disk to Temp Buffer + call load_kernel + + ; 2. Enable A20 Line in al, 0x92 or al, 2 out 0x92, al + + ; 3. VBE Graphics Setup mov ax, VBE_MAGIC + VBE_GET_INFO - mov di, vbe_info_block + mov di, VBE_INFO_BLOCK int 0x10 cmp ax, 0x004F jne .graphics_error - mov cx, [vbe_info_block + 14] - mov si, [vbe_info_block + 16] + + mov cx, [VBE_INFO_BLOCK + 14] + mov si, [VBE_INFO_BLOCK + 16] + .mode_loop: push cx mov ax, VBE_MAGIC + VBE_GET_MODE_INFO mov cx, [si] - mov di, mode_info_block + mov di, MODE_INFO_BLOCK int 0x10 cmp ax, 0x004F jne .next_mode - cmp word [mode_info_block +18], TARGET_WIDTH + + cmp word [MODE_INFO_BLOCK + 18], TARGET_WIDTH jne .next_mode - cmp word [mode_info_block +20], TARGET_HEIGHT + cmp word [MODE_INFO_BLOCK + 20], TARGET_HEIGHT jne .next_mode - cmp word [mode_info_block +25], TARGET_BPP + cmp word [MODE_INFO_BLOCK + 25], TARGET_BPP jne .next_mode + + ; Found mode! Set it. mov ax, VBE_MAGIC + VBE_SET_MODE mov bx, [si] - or bx, 1 << 14 ;For the Linear Frame Buffer (LFB) + or bx, 1 << 14 int 0x10 cmp ax, 0x004F jne .graphics_error + + ; Save VBE info for kernel + push es + xor ax, ax + mov es, ax mov edi, 0x8000 - mov esi, mode_info_block + mov esi, MODE_INFO_BLOCK mov ecx, 256 rep movsb - jmp .continue_boot + pop es + + ; FIX: Jump to the global label (no dot) + jmp enter_pm + .next_mode: add si, 2 pop cx loop .mode_loop + .graphics_error: cli hlt -.continue_boot + +; --- Disk Loading Routine --- +load_kernel: + mov ax, KERNEL_TEMP_ADDR + mov es, ax + xor bx, bx + + mov ah, 0x02 + mov al, SECTORS_TO_READ + mov ch, 0 + mov dh, 0 + mov cl, 2 + mov dl, [boot_drive] + int 0x13 + jc .disk_error + ret + +.disk_error: + cli + hlt + +; --- Protected Mode Entry (Global Label) --- +enter_pm: + cli lgdt [gdt_descriptor] mov eax, cr0 or eax, 1 @@ -74,25 +132,32 @@ start_protected_mode: mov fs, ax mov gs, ax mov ss, ax - mov esp, 0x90000 ; Set stack pointer to safe location + mov esp, 0x90000 + + ; Copy Kernel to 1MB + mov esi, 0x10000 + mov edi, KERNEL_TARGET_ADDR + mov ecx, (SECTORS_TO_READ * 512) / 4 + rep movsd + + ; Jump to Kernel (1MB) push dword 0x8000 - call kernel_main + mov eax, KERNEL_TARGET_ADDR + call eax + cli hlt - jmp $ -; GDT for bootloader + +; Variables +boot_drive db 0 gdt_start: dd 0x0, 0x0 dw 0xFFFF, 0x0000, 0x9A, 0xCF, 0x00 dw 0xFFFF, 0x0000, 0x92, 0xCF, 0x00 gdt_end: gdt_descriptor: - dw gdt_end - gdt_start - 1 ; Limit + dw gdt_end - gdt_start - 1 dd gdt_start -bss_start: - vbe_info_block resb 512 - mode_info_block resb 256 -bss_end: -; Boot signature + times 510-($-$$) db 0 dw 0xAA55 \ No newline at end of file diff --git a/boot.bin b/boot.bin new file mode 100644 index 0000000000000000000000000000000000000000..afb5ca8fe2e9935d72dbb5fb4b90a698f8ae2b92 GIT binary patch literal 512 zcmaFGTEoC#c%bh_-+{ghdl+gu#6Hx#C}VgsiHGUgq#gbY`xz#j6=?q9Uz*s>$2Xzd zOkhIbjsS*kp8X7yAmYxAc0!XFSWB%N?L;PBU@A3kwv(KsP^z;dkfB?q@ic=2M41vB z(2@gb`xzP-7}EAJOahWS85kKDJ}+T^t= fb->width || fb_y < 0 || fb_y >= fb->height) continue; - uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->base_address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); + uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); if (cursor_bitmap[cy][byte_index] & mask) { cursor_fg_buffer[cy * CURSOR_WIDTH + cx] = *fb_pixel; *fb_pixel = 0xFFFFFFFF; // White color for cursor @@ -58,12 +59,15 @@ void cursor_hide(void) { } void cursor_update(FrameBuffer* fb, int x, int y) { if (visible) { + // Invalidate the area where the cursor was + dirty_rect_add(prev_x, prev_y, CURSOR_WIDTH, CURSOR_HEIGHT); + for (int cy = 0; cy < CURSOR_HEIGHT; cy++) { for (int cx = 0; cx < CURSOR_WIDTH; cx++) { int fb_x = prev_x + cx; int fb_y = prev_y + cy; - if (fb_x < 0 || fb_x >= fb->width || fb_y < 0 || fb_y >= fb->height) continue; - uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->base_address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); + if (fb_x < 0 || fb_x >= (int)fb->width || fb_y < 0 || fb_y >= (int)fb->height) continue; + uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); if (cursor_bitmap[cy][cx / 8] & (1 << (7 - (cx % 8)))) { *fb_pixel = cursor_fg_buffer[cy * CURSOR_WIDTH + cx]; } else { @@ -72,6 +76,9 @@ void cursor_update(FrameBuffer* fb, int x, int y) { } } } + // Invalidate the area where the cursor will be + dirty_rect_add(x, y, CURSOR_WIDTH, CURSOR_HEIGHT); + cursor_draw(fb, x, y); } #undef CURSOR_WIDTH diff --git a/cursor.o b/cursor.o new file mode 100644 index 0000000000000000000000000000000000000000..73b42f8088ed673dd6ad937fc07c7ec2ddf2a176 GIT binary patch literal 2179 zcmZ`)Uuaup6hB|@Z5n2{H%OF-9l7ddY%FBS)}eD9P1epmxItOFKjOMHX_7V4xscq{ zw$xg@i}n%&dl2^EUgjPIU&>(gN#thj7PNw_11-p~DjTisL;KWjj>dEDO>fdg4}ACg zo%5aVcg}at<@-)B8<5O30_-#p&wNUJNHMVa(Hj7G1~AW?`b#)T(An#YMU+U5pB?cG zS7SgJ1i$W!W-_%_i5#Dkap={3>FtCP`utSK*Bji|vVF4`)s;Fwe{f&m;5J7cH8-B& zTRbZX9S8FZmKq6_QA);26_MBU)zfDK>T*6 z=|gLWkMWt6@m3kKkMpCl{qV>3%tLXi$C*Fr(3d%J@@KR<#i`%K$$2)*^?-Iie_;K- z`bQH+;J?Q{!Gp)zn)XX^le^-06P+EHGoRHcEFRR1Rx;{^F|%J>MHd&k*wqqK?=iLP z6mxqpGc@}#{T8z*#H$^lLfymx>WusS3*nw=I?oL<T2)vsArS!wutf zVi~)U{9I1YwqU_{%`2BWWQP;?;cTaQkw|duoQA%5u1Hp^v$==mL5hs@ug z^swm0Zc`bMcO#7#S7l?HRto6a6YXx{Iz<4qOT{Hm@e%dQo$r=q?S$+K{D5JbmtU{+ zH-9}Zk*~X=t3^gdeBxB%xw)aWLudH0m2s>gWFH+GvyUx^Q|~zQ7aVv@x4wuC`(2#U z#mPHtUYq4?#eX<)YG5a5v+EDkzna9G5A)~c=JZz-gt}vJYi?xEe!UeRlce6@KeBbn-|x6qe}s6H;Zg~;6dqlM6=+i zSV%%vs+0>_ETmXy!a}}8av+Wx$z~bgBJ0bhGndo8KGU}KeWd~zNYH?htI}k^a4H=i z3=bKdrfPCvT853)ie)gFNk+|ZbfFlR3ee>!;izY(UYK&AGE@J}T}Kf~70tAClLZ~B z%n7svG1q!#0ar|+j`seikGWp^x}h6zOvl5}n^u+Dm(4gStADa;Uo|5`R{yTmzG%it znN$r@gFdZbdVV;zw`QdZ3l&K3HRg<8V%#p*EERhS-=Jn@AdifUfG^%3PNXB3;t)3f zh;Z`5q+%(tbmSvTi6)gxk(8w-E{3DoL?WKHEYUhke==5O&Zh7wkN;2fSTd~)htqi9 Jgd?#S{0ouGv_}8{ literal 0 HcmV?d00001 diff --git a/dirty_rect.c b/dirty_rect.c new file mode 100644 index 0000000..219c408 --- /dev/null +++ b/dirty_rect.c @@ -0,0 +1,52 @@ +#include "dirty_rect.h" +#include + +static Rect dirty_rects[MAX_DIRTY_RECTS]; +static int dirty_rect_count = 0; + +static inline int max(int a, int b) { return a > b ? a : b; } +static inline int min(int a, int b) { return a < b ? a : b; } + +void dirty_rect_init() { + dirty_rect_count = 0; +} + +void dirty_rect_add(int x, int y, int width, int height) { + if (width <= 0 || height <= 0) { + return; + } + + Rect new_rect = {x, y, width, height}; +restart_scan: + for (int i = 0; i < dirty_rect_count; ++i) { + Rect* existing = &dirty_rects[i]; + if (!(new_rect.x >= existing->x + existing->width || + new_rect.x + new_rect.width <= existing->x || + new_rect.y >= existing->y + existing->height || + new_rect.y + new_rect.height <= existing->y)) + { + new_rect.x = min(existing->x, new_rect.x); + new_rect.y = min(existing->y, new_rect.y); + int x2 = max(existing->x + existing->width, new_rect.x + new_rect.width); + int y2 = max(existing->y + existing->height, new_rect.y + new_rect.height); + new_rect.width = x2 - new_rect.x; + new_rect.height = y2 - new_rect.y; + dirty_rects[i] = dirty_rects[dirty_rect_count - 1]; + dirty_rect_count--; + goto restart_scan; + } + } + if (dirty_rect_count < MAX_DIRTY_RECTS) { + dirty_rects[dirty_rect_count++] = new_rect; + } else { + for (int i = 1; i < dirty_rect_count; i++) { + dirty_rect_add(dirty_rects[i].x, dirty_rects[i].y, dirty_rects[i].width, dirty_rects[i].height); + } + dirty_rect_count = 1; + } +} + +const Rect* dirty_rect_get_all(int* count) { + *count = dirty_rect_count; + return dirty_rects; +} \ No newline at end of file diff --git a/dirty_rect.h b/dirty_rect.h new file mode 100644 index 0000000..6b1adcf --- /dev/null +++ b/dirty_rect.h @@ -0,0 +1,28 @@ +#ifndef DIRTY_RECT_H +#define DIRTY_RECT_H + +#include "graphics.h" + +#define MAX_DIRTY_RECTS 32 + +typedef struct { + int x, y, width, height; +} Rect; + +/** + * @brief Initializes or clears the dirty rectangle list. + */ +void dirty_rect_init(); + +/** + * @brief Adds a new rectangle to the list of dirty regions. + * This function will attempt to merge the new rectangle with existing ones. + */ +void dirty_rect_add(int x, int y, int width, int height); + +/** + * @brief Provides access to the list of dirty rectangles for the renderer. + */ +const Rect* dirty_rect_get_all(int* count); + +#endif // DIRTY_RECT_H \ No newline at end of file diff --git a/dirty_rect.o b/dirty_rect.o new file mode 100644 index 0000000000000000000000000000000000000000..a3a42912e42a6f738c45370a958b1799a8329735 GIT binary patch literal 1570 zcmZ`(O=uHQ5PmPa)kU}6twd1U!#gac)v~stV61{^8bwL`Y5hfNOxuk{(pJ)q)KY73 ziMp(j9zFHq)su=Sf}{=BUqn0!dJs`i5RF>Yi;Xk8={E6aU}nB~Z)V=Sc|RdqMUd9> zgm`VlQ&rc7bsIZE_7L(4;APISt3ffc>xkMH)uYbPf8}P?G?5dgF6>e2q|9Rour`4pnWA)QjDi)G%~7TK7K5?Y=VnTvU(Arw z2no2b2&g`L6WuMrIv~);ZQa7y+BTR!ty;r81S;k%H!K2RZKuVtztoO^v*4b||71_z6m|0yCg^ zD^M_b<^8kSV$o-}`OI^tj~F+X3o5fZ6lJ{O?3ya0# z+@7_$J@@0Dp8(&(J=;F^`9ev&wG=WCQ?}14KVCsw1Az^!u~R#_zL~YB;t8GgoMPdw zgI#ObiR9pMtygbit?Se^D)h;D3xv>-PC`coS|{@S1!#c`+3SJvsx1aa+6auT#h91a zCV!2P@w8W0Z9C7MU9wZ4Y_G~FL{g4E6o&cVK*d?Hm@Y>e^FCf?m z2kmyzcNcje#+j{kQM-$_yXdNmuDb}Yf)o4QMZa9cV2wq^jb;eOHFF{He!CL3ZeVk-vX%OEnveQxQ%HL6fJ&z&;%z)>k4uVyH zHU5r*383it4da-8ZMdG z4UVQ!mPQmagic = HEAP_MAGIC; + first_segment->size = size - sizeof(heap_header_t); + first_segment->free = true; + first_segment->next = NULL; + first_segment->prev = NULL; +} + +void* heap_alloc(size_t size){ + spinlock_acquire(&heap_lock); + + if (size == 0) { + spinlock_release(&heap_lock); + return NULL; + } + size_t aligned_size = align(size); + heap_header_t* current = first_segment; + while (current != NULL) { + if (current->free && current->size >= aligned_size) { + // Check if the remaining space is large enough for a new header and a minimal allocation. + if (current->size >= aligned_size + sizeof(heap_header_t) + HEAP_ALIGNMENT) { // Smallest alloc is HEAP_ALIGNMENT + heap_header_t* new_segment = (heap_header_t*)((uint8_t*)current + sizeof(heap_header_t) + aligned_size); + new_segment->magic = HEAP_MAGIC; + new_segment->size = current->size - aligned_size - sizeof(heap_header_t); + new_segment->free = true; + new_segment->next = current->next; + new_segment->prev = current; + + if (current->next != NULL) { + current->next->prev = new_segment; + } + current->next = new_segment; + current->size = aligned_size; + } + current->free = false; + spinlock_release(&heap_lock); + return (void*)((uint8_t*)current + sizeof(heap_header_t)); + } + current = current->next; + } + // Out of memory + spinlock_release(&heap_lock); + return NULL; +} + +void heap_free(void* ptr){ + spinlock_acquire(&heap_lock); + + if (ptr == NULL) { + spinlock_release(&heap_lock); + return; + } + heap_header_t* header = (heap_header_t*)((uint8_t*)ptr - sizeof(heap_header_t)); + if (header->magic != HEAP_MAGIC) { + // PANIC("Heap corruption detected!"); + spinlock_release(&heap_lock); + return; // Or better, panic. + } + + header->free = true; + heap_header_t* next = header->next; + if (next != NULL && next->free) { + header->size += sizeof(heap_header_t) + next->size; + header->next = next->next; + if (next->next != NULL) { + next->next->prev = header; + } + } + + // Coalesce with previous block if it's free + heap_header_t* prev = header->prev; + if (prev != NULL && prev->free) { + prev->size += sizeof(heap_header_t) + header->size; + prev->next = header->next; + if (prev->next != NULL) { // This was header->next before, which is wrong + prev->next->prev = prev; + } + } + + spinlock_release(&heap_lock); +} + +#undef heap_start_address +#undef heap_size +#undef first_segment +#undef heap_init +#undef heap_alloc +#undef heap_free +#undef heap_header_t +#define kmalloc(size) heap_alloc(size) +#define kfree(ptr) heap_free(ptr) diff --git a/heap.h b/heap.h new file mode 100644 index 0000000..9349645 --- /dev/null +++ b/heap.h @@ -0,0 +1,11 @@ +#ifndef HEAP_H +#define HEAP_H +#include +#include +#include +void heap_init(uint32_t start_address, uint32_t size); +void* kmalloc(size_t size); +void kfree(void* ptr); +#define malloc(size) kmalloc(size) +#define free(ptr) kfree(ptr) +#endif // HEAP_H \ No newline at end of file diff --git a/kernel.c b/kernel.c index 81f61f7..df37c02 100644 --- a/kernel.c +++ b/kernel.c @@ -19,6 +19,7 @@ #include "window.h" #include "mouse.h" #include "cursor.h" +#include "dirty_rect.h" void counter_task(){ int i=0; while(1){ @@ -29,18 +30,18 @@ Widget* widget_list_head=NULL; Window* window_list_head=NULL; Window* window_list_tail=NULL; void on_my_button_click(){ - if(!g_widget_font)return; ButtonData* data=(ButtonData*)widget_list_head->data; if(!data)return; data->bg_color=data->press_color; data->border_color=data->press_border; } void on_my_button_release(){ - if(!g_widget_font)return; ButtonData* data=(ButtonData*)widget_list_head->data; if(!data)return; data->bg_color=data->base_color; - data->border_color=data->border_color;} + data->border_color=data->border_color; +} + typedef struct { uint16_t attributes; uint8_t window_a, window_b; @@ -130,6 +131,8 @@ void kernel_main(void) { window_list_head = main_window; window_list_tail = main_window; init_widget_system(); + window_manager_init(); + dirty_rect_init(); widget_set_font(&my_font); //Scheduler takes over, chillax!! @@ -140,30 +143,54 @@ void kernel_main(void) { uint8_t last_buttons = 0; int32_t last_x = -1, last_y = -1; + // Initial full-screen draw + dirty_rect_add(0, 0, fb.width, fb.height); + while(1) { - window_manager_handle_mouse(&window_list_head, &window_list_tail, mouse_x, mouse_y, mouse_buttons, last_buttons); - wm_process_mouse(mouse_x, mouse_y, mouse_buttons, last_buttons); - cursor_update(&fb, mouse_x, mouse_y); - widget_update_all(widget_list_head, &fb); - window_update_all(window_list_head, &fb); - if(mouse_buttons != last_buttons || mouse_x != last_x || mouse_y != last_y) { - window_draw_all(window_list_head, &fb); + // --- Input and State Update Phase --- + bool mouse_moved = (mouse_x != last_x || mouse_y != last_y); + bool buttons_changed = (mouse_buttons != last_buttons); + + if (mouse_moved || buttons_changed) { + // Invalidate old cursor position + dirty_rect_add(last_x, last_y, 16, 16); // Assuming cursor size + + // Handle window manager logic (dragging, etc.) + window_manager_handle_mouse(&window_list_head, &window_list_tail, mouse_x, mouse_y, mouse_buttons, last_buttons); + + // Invalidate new cursor position + dirty_rect_add(mouse_x, mouse_y, 16, 16); + last_x = mouse_x; last_y = mouse_y; - cursor_history[history_index].x = mouse_x; - cursor_history[history_index].y = mouse_y; - history_index = (history_index + 1) % CURSOR_TRAIL_LENGTH; - for (int i = 0; i < CURSOR_TRAIL_LENGTH; i++) { - int current_idx = (history_index - 1 - i + CURSOR_TRAIL_LENGTH) % CURSOR_TRAIL_LENGTH; - int32_t x = cursor_history[current_idx].x; - int32_t y = cursor_history[current_idx].y; - // Fade the tail from white to gray - uint8_t intensity = 255 - (i * (255 / CURSOR_TRAIL_LENGTH)); - uint32_t color = (intensity << 16) | (intensity << 8) | intensity; - fb_set_pixel(&fb, x, y, color); - } last_buttons = mouse_buttons; } + + // --- Drawing Phase --- + int dirty_count; + const Rect* rects = dirty_rect_get_all(&dirty_count); + + if (dirty_count > 0) { + // For each dirty rectangle, redraw all windows that intersect with it + for (int i = 0; i < dirty_count; i++) { + const Rect* dirty = &rects[i]; + Window* current = window_list_head; + while (current) { + // Simple intersection check + if (!(current->x > dirty->x + dirty->width || current->x + current->width < dirty->x || + current->y > dirty->y + dirty->height || current->y + current->height < dirty->y)) { + window_draw(current, &fb); // In a more advanced system, we'd clip the drawing. + } + current = current->next; + } + } + // After drawing, clear the list for the next frame. + dirty_rect_init(); + } + + // Always draw the cursor on top of the final scene + cursor_update(&fb, mouse_x, mouse_y); + asm volatile("hlt"); } } diff --git a/keyboard.c b/keyboard.c index e52084b..7080361 100644 --- a/keyboard.c +++ b/keyboard.c @@ -87,6 +87,10 @@ char keyboard_getchar(void) { } char ch = key_buffer[buffer_start]; + if (ch !=0){ + window_handle_key(ch); + shell_handle_input(ch); + } buffer_start = (buffer_start + 1) % 256; return ch; } diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..9aa9dca --- /dev/null +++ b/linker.ld @@ -0,0 +1,27 @@ +ENTRY(kernel_main) + +SECTIONS +{ + . = 0x100000; + + .text BLOCK(4K) : ALIGN(4K) + { + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } +} \ No newline at end of file diff --git a/sync.h b/sync.h new file mode 100644 index 0000000..69a83ca --- /dev/null +++ b/sync.h @@ -0,0 +1,35 @@ +#ifndef SYNC_H +#define SYNC_H + +#include + +typedef struct { + volatile bool locked; +} spinlock_t; + +/** + * @brief Initializes a spinlock to the unlocked state. + * @param lock Pointer to the spinlock. + */ +static inline void spinlock_init(spinlock_t* lock) { + lock->locked = false; +} + +/** + * @brief Acquires the spinlock, spinning until it is free. + * This uses an atomic test-and-set operation. + * @param lock Pointer to the spinlock. + */ +static inline void spinlock_acquire(spinlock_t* lock) { + while (__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE)); +} + +/** + * @brief Releases the spinlock. + * @param lock Pointer to the spinlock. + */ +static inline void spinlock_release(spinlock_t* lock) { + __atomic_clear(&lock->locked, __ATOMIC_RELEASE); +} + +#endif // SYNC_H \ No newline at end of file diff --git a/widget.h b/widget.h index d5f73b3..8af0dc8 100644 --- a/widget.h +++ b/widget.h @@ -32,6 +32,14 @@ typedef enum { WIDGET_RADIOGROUP, WIDGET_VOICEINPUT }WidgetType; + +typedef enum { + EVENT_MOUSE_CLICK = 1, + EVENT_MOUSE_RELEASE = 2, + EVENT_MOUSE_HOVER = 3, + EVENT_MOUSE_MOVE = 4, +} event_type_t; + typedef struct Widget{ WidgetType type; int x,y,width,height; diff --git a/window.c b/window.c index 2903574..b12f092 100644 --- a/window.c +++ b/window.c @@ -1,6 +1,8 @@ #include "window.h" #include #include +#include "sync.h" +#include "dirty_rect.h" #define WINDOW_BG_COLOR 0xECECEC #define TITLE_BAR_COLOR 0x2C2C2C #define TITLE_TEXT_COLOR 0xFFFFFF @@ -14,8 +16,10 @@ extern Font* g_widget_font; extern Window* window_list_head; extern Window* window_list_tail; +static spinlock_t wm_lock; static Widget* last_hivered_widget = NULL; -Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar){ +static Window* focused_window = NULL; +Window* create_window(int x,int y,int width,int height,const char* title,bool has_title_bar){ Window* window=(Window*)malloc(sizeof(Window)); if(!window)return NULL; window->x=x; @@ -28,9 +32,6 @@ Window* create_window(int x,int y,int width,int height,char** title,bool has_tit window->child_widgets_tail=NULL; window->next=NULL; window->prev=NULL; - window->parent=NULL; - window->child=NULL; - window->sibling=NULL; window->close_button_hovered = false; return window; } @@ -85,25 +86,19 @@ void window_free(Window* window){ void window_draw(Window* window,FrameBuffer* fb){ if(!window)return; // Draw window background - for(int y=0;yheight;y++){ - for(int x=0;xwidth;x++){ - fb_set_pixel(fb,window->x+x,window->y+y,WINDOW_BG_COLOR); - } - } + fill_rectangle(fb, window->x, window->y, window->width, window->height, WINDOW_BG_COLOR); + // Draw title bar if present if(window->has_title_bar&&window->title){ - for(int y=0;ywidth;x++){ - fb_set_pixel(fb,window->x+x,window->y+y,TITLE_BAR_COLOR); - } - } + fill_rectangle(fb, window->x, window->y, window->width, TITLE_BAR_HEIGHT, TITLE_BAR_COLOR); + // Draw title text (centered) if(g_widget_font){ - int text_width=strlen(*window->title)*g_widget_font->char_width; + int text_width=strlen(window->title)*g_widget_font->char_width; int text_height=g_widget_font->char_height; int text_x=window->x+window->width/2-text_width/2; int text_y=window->y+(TITLE_BAR_HEIGHT-text_height)/2; - draw_string(fb,text_x,text_y,*window->title,TITLE_TEXT_COLOR,g_widget_font); + draw_string(fb,text_x,text_y,window->title,TITLE_TEXT_COLOR,g_widget_font); } // Draw close button @@ -134,38 +129,36 @@ void window_handle_event(Window* window,int mouse_x,int mouse_y,int event){ } void window_on_click(Window* window,int mouse_x,int mouse_y,int button){ if(!window)return; - widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,1); // 1 for click + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_CLICK); } void window_on_release(Window* window,int mouse_x,int mouse_y,int button){ if(!window)return; - widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,2); // 2 for release + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_RELEASE); } void window_on_hover(Window* window,int mouse_x,int mouse_y){ if(!window)return; - widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,3); // 3 for hover + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_HOVER); } void window_on_move(Window* window,int mouse_x,int mouse_y){ if(!window)return; - widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,4); // 4 for move + widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_MOVE); } -void widget_draw_all(Widget* head,FrameBuffer* fb){ - Widget* current=head; - while(current){ - widget_draw(current,fb); - current=current->next; - } + +void window_manager_init() { + spinlock_init(&wm_lock); } void window_destroy(Window** head, Window** tail, Window* win_to_destroy) { if (!win_to_destroy) return; + spinlock_acquire(&wm_lock); + // Unlink from the list if (win_to_destroy->prev) { win_to_destroy->prev->next = win_to_destroy->next; } else { // It's the head *head = win_to_destroy->next; } - if (win_to_destroy->next) { win_to_destroy->next->prev = win_to_destroy->prev; } else { // It's the tail @@ -173,6 +166,8 @@ void window_destroy(Window** head, Window** tail, Window* win_to_destroy) { } // Free associated widgets and the window itself + spinlock_release(&wm_lock); + window_free_widgets(win_to_destroy); free(win_to_destroy); } @@ -183,6 +178,8 @@ void window_bring_to_front(Window** head, Window** tail, Window* win) { return; // Already at the front or invalid window } + spinlock_acquire(&wm_lock); + // Unlink from current position if (win->prev) { win->prev->next = win->next; @@ -201,6 +198,8 @@ void window_bring_to_front(Window** head, Window** tail, Window* win) { win->prev = *tail; win->next = NULL; *tail = win; + + spinlock_release(&wm_lock); } // State for window dragging, kept static within this file @@ -210,6 +209,8 @@ static int32_t drag_offset_y = 0; void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, int32_t mouse_y, uint8_t mouse_buttons, uint8_t last_buttons) { + spinlock_acquire(&wm_lock); + Window* top_win = *tail; if (top_win) { int btn_x = top_win->x + top_win->width - CLOSE_BUTTON_WIDTH - CLOSE_BUTTON_MARGIN; @@ -235,8 +236,9 @@ void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, if (mouse_x >= btn_x && mouse_x < btn_x + CLOSE_BUTTON_WIDTH && mouse_y >= btn_y && mouse_y < btn_y + CLOSE_BUTTON_HEIGHT) { - window_destroy(head, tail, win); - // Don't proceed to drag checks + window_destroy(head, tail, win); // This function handles its own locking + spinlock_release(&wm_lock); // Release lock before returning + return; // Exit immediately after destroying window } else if (mouse_x >= win->x && mouse_x < win->x + win->width && mouse_y >= win->y && mouse_y < win->y + TITLE_BAR_HEIGHT) { @@ -259,35 +261,14 @@ void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, // 3. Mouse moved while dragging if (dragged_window != NULL) { + // Invalidate the old position of the window before moving it + dirty_rect_add(dragged_window->x, dragged_window->y, dragged_window->width, dragged_window->height); + dragged_window->x = mouse_x - drag_offset_x; dragged_window->y = mouse_y - drag_offset_y; } -} -void widget_draw(Widget* widget,FrameBuffer* fb){ - if(!widget||!widget->draw)return; - widget->draw(widget,fb); -} -void widget_update(Widget* widget,FrameBuffer* fb){ - if(!widget||!widget->update)return; - widget->update(widget,fb); -} -void widget_handle_event(Widget* widget,int mouse_x,int mouse_y,int event){ - if(!widget||!widget->handle_event)return; - widget->handle_event(widget,mouse_x,mouse_y,event); -} -void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ - Widget* current=head; - while(current){ - widget_handle_event(current,mouse_x,mouse_y,event); - current=current->next; - } -} -void widget_draw_all(Widget* head,FrameBuffer* fb){ - Widget* current=head; - while(current){ - widget_draw(current,fb); - current=current->next; - } + + spinlock_release(&wm_lock); } void widget_update_all(Widget* head,FrameBuffer* fb){ Widget* current=head; @@ -306,3 +287,36 @@ void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ void wm_process_mouse(int mouse_x,int mouse_y,uint8_t mouse_buttons,uint8_t last_buttons){ window_manager_handle_mouse(&window_list_head,&window_list_tail,mouse_x,mouse_y,mouse_buttons,last_buttons); } +void window_handle_key(char key){ + if(!window_list_tail)return; + // For now, just a placeholder to show where key handling would go. + // In a real implementation, you'd route this to the focused window's widgets. +} +void window_draw_all(Window* head,FrameBuffer* fb){ + spinlock_acquire(&wm_lock); + Window* current=head; + while(current){ + window_draw(current,fb); + current=current->next; + } + spinlock_release(&wm_lock); +} +void window_set_focus(Window* window){ + if(!window)return; + spinlock_acquire(&wm_lock); + window_bring_to_front(&window_list_head,&window_list_tail,window); + spinlock_release(&wm_lock); + focused_window=window; +} +Window* wm_get_focused_window(){ + return focused_window; +} +void window_update_all(Window* head,FrameBuffer* fb){ + spinlock_acquire(&wm_lock); + Window* current=head; + while(current){ + window_update(current,fb); + current=current->next; + } + spinlock_release(&wm_lock); +} \ No newline at end of file diff --git a/window.h b/window.h index e281e84..93e6767 100644 --- a/window.h +++ b/window.h @@ -3,21 +3,18 @@ #include "graphics.h" #include "widget.h" #include -typedef struct{ +typedef struct Window { int x,y,width,height; - char** title; + const char* title; // Use const char* for simple, static titles bool has_title_bar; Widget* child_widgets_head; Widget* child_widgets_tail; struct Window* next; struct Window* prev; - struct Window* parent; - struct Window* child; - struct Window* sibling; bool close_button_hovered; }Window; -Window* create_window(int x,int y,int width,int height,char** title,bool has_title_bar); +Window* create_window(int x,int y,int width,int height,const char* title,bool has_title_bar); void window_add_widget(Window* window,Widget* widget); void window_remove_widget(Window* window,Widget* widget); void window_draw(Window* window,FrameBuffer* fb); @@ -30,4 +27,8 @@ void wm_process_mouse(int mouse_x,int mouse_y,uint8_t mouse_buttons,uint8_t last void window_destroy(Window** head, Window** tail, Window* win_to_destroy); void window_bring_to_front(Window** head, Window** tail, Window* win); void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, int32_t mouse_y, uint8_t mouse_buttons, uint8_t last_buttons); +void wm_set_focus(Window* window); +void window_free_widgets(Window* window); +void window_handle_key(char key); +void window_free(Window* window); #endif \ No newline at end of file From dd881df5f8897e6d78451b21b79ad5cddd447c9e Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:27:48 +0530 Subject: [PATCH 15/18] patch-1b --- Makefile | 5 -- console.c | 41 ++++++++++++ console.h | 8 +++ console.o | Bin 0 -> 1109 bytes cursor.c | 2 +- cursor.o | Bin 2179 -> 2179 bytes font.h | 2 +- font.o | Bin 0 -> 4620 bytes gdt.c | 4 +- gdt.o | Bin 0 -> 1450 bytes graphics.c | 86 +++++++++++++----------- graphics.h | 35 +++++----- graphics.o | Bin 0 -> 3722 bytes heap.c | 4 +- heap.o | Bin 0 -> 1332 bytes idt.c | 192 +++++++++++++---------------------------------------- idt.h | 1 + idt.o | Bin 0 -> 7524 bytes kernel.c | 54 ++++++--------- paging.h | 19 ++++-- syscall.c | 2 + syscall.h | 1 + task.h | 2 + widget.h | 9 ++- 24 files changed, 218 insertions(+), 249 deletions(-) create mode 100644 console.c create mode 100644 console.h create mode 100644 console.o create mode 100644 font.o create mode 100644 gdt.o create mode 100644 graphics.o create mode 100644 heap.o create mode 100644 idt.o diff --git a/Makefile b/Makefile index fba4187..f2d55a9 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,7 @@ -# SimpleOS Flat Makefile - -# Tool definitions CC = i686-w64-mingw32-gcc LD = i686-w64-mingw32-ld OBJCOPY = i686-w64-mingw32-objcopy NASM = nasm - -# Flags: 32-bit, no standard libs, include current directory CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. # Auto-detect all .c files in the current folder diff --git a/console.c b/console.c new file mode 100644 index 0000000..e59aff8 --- /dev/null +++ b/console.c @@ -0,0 +1,41 @@ +#include "console.h" +static FrameBuffer* console_fb = NULL; +static Font* console_font = NULL; +void console_init(FrameBuffer* fb, Font* font) { + console_fb = fb; + console_font = font; +} +void console_write(const char* str) { + if (!console_fb || !console_font) return; + static uint32_t cursor_x = 0; + static uint32_t cursor_y = 0; + + while (*str) { + char c = *str++; + if (c == '\n') { + cursor_x = 0; + cursor_y += console_font->char_height; + continue; + } + + cursor_x += console_font->char_width; + if (cursor_x + console_font->char_width > console_fb->width) { + cursor_x = 0; + cursor_y += console_font->char_height; + } + } +} +#undef console_fb +#undef console_font +#undef console_write +#define console_init console_init +#define console_write console_write +#define console_fb console_fb +#define console_font console_font +#define console_write console_write +#define console_init console_init +#define console_fb console_fb +#define console_font console_font +#define console_write console_write +#define console_init console_init +#define console_fb console_fb \ No newline at end of file diff --git a/console.h b/console.h new file mode 100644 index 0000000..939693e --- /dev/null +++ b/console.h @@ -0,0 +1,8 @@ +#ifndef CONSOLE_H +#define CONSOLE_H +#include +#include +#include +void console_init(FrameBuffer* fb, Font* font); +void console_write(const char* str); +#endif // CONSOLE_H \ No newline at end of file diff --git a/console.o b/console.o new file mode 100644 index 0000000000000000000000000000000000000000..2de7e666762682500c932be4838142a35ce946ca GIT binary patch literal 1109 zcmZ`&-D?v;5Z}GKh7jW!FfXFQK7^`Rw!LaWMWJVvJg86-KPXnud|YfKCgpCUZKxpB zsNpE+t4~5-`~$={p&I=98`O7S{1>bdBP1)4LAh|( zgv6nF4ekeM8gfvQpo}cu;nk8TN#_4%p3LmkYxm>+DK#sW{74z1BUqB91X@j?eO$ z!QBu-I|V{FlJsEOFrLF!c$SAiam@XoD0qxeLUN!TP-2_Ou4bF*XL{buJT+`HyE&mX z`ew%dY^LomX43v-LIZpWCTK$15MhrHVb>5{jL@YB1rd4~AqFS~nw1lUh}Y^37dVtZ zyM)}Ol~&VlHC$c^No5ZxPYEL$9%&?r2ps{0_opi*O#DCKC^~%w7WWxS{4e19(?@0w^Wy(NcBXiH>dm?sMzwMbx0= fb->width || fb_y < 0 || fb_y >= fb->height) continue; + if (fb_x < 0 || fb_x >=(int)fb->width || fb_y < 0 || fb_y >= (int)fb->height) continue; uint32_t* fb_pixel = (uint32_t*)((uint8_t*)fb->address + (fb_y * fb->pitch) + (fb_x * (fb->bitsPerPixel / 8))); if (cursor_bitmap[cy][byte_index] & mask) { cursor_fg_buffer[cy * CURSOR_WIDTH + cx] = *fb_pixel; diff --git a/cursor.o b/cursor.o index 73b42f8088ed673dd6ad937fc07c7ec2ddf2a176..781f28964a8f173a6b8da07dbc47a0a4a3cc99bb 100644 GIT binary patch delta 32 ocmZn`Y!=)wnNir%m8I@YgN+J9>9g({6%NZ9g({6%OlKj^fSB81J$H0JDP&K>z>% diff --git a/font.h b/font.h index 416bb78..88ba8be 100644 --- a/font.h +++ b/font.h @@ -1,5 +1,5 @@ #ifndef FONT_H #define FONT_H #include -extern const uint8_t font[]; +extern const uint8_t font[256][16]; #endif \ No newline at end of file diff --git a/font.o b/font.o new file mode 100644 index 0000000000000000000000000000000000000000..b96c625105b6631139f9d6fd57c6112cccd50edd GIT binary patch literal 4620 zcmeHLPm3H?5U=T-EIEwY-WmyE4jx8a#%EAyWFSMbpa+FuPM+)}?rNklOEQMZ@)&xD zCJaGjS@z;B2wnz1fC$23U`~F6>|t-YdhjrZq1&pS>3a2E?>M_TDOfYiykAwl`uD0| zzwVD~7l7#E>j1A5qYJfmZ>!%c#>;=2prZB{w|cjhs}zzhsH67n2M<=LK|*@>9fLl= zu`{s?QTLtqY~}{SW7L&|e!CLWc(C`=-futb4NCqXf1W>kku#37EYqPeV|oFx)W2 z01XE)BZE}G-&Y1=w1a@CWYKsa5+H0bO2sArWUn$GO_b^=7sV*Jc`hfEif8;U>`D7U z@Q?N|f2F`wAdX|pQygdbF}zSe?Qcv?IVTfbq3vy+6Y3<vgu5CCN<6aq>*s&%F9Yzu9Gd^iN-j2cBne5xa}6IZjxP^S_t*;%v*GRzxQM zS3S?O^wZIwqtwKQ(IA=i8BWFrGXCN3KOQ`JZ1l0%NX9-ThXzD^!{L*3modquKWb;W zK3Ng3X~@F7u#b3iv*oir#0Ljs)6ggmH$}Y>x8!z~742g3(|EZ=k%^xczp?JIeZ5X( zHw-adqH!tkogr~Uj zVtZjJfP1~U{@i-HayK4#e|52Ned^G?ADyan4yJp4SvB?ff=a!7LCdgvz5UnmY(Ztd z|KoWD{;lpEu4t@g)`A=ap4vKD>VYgJ$c~t%u=8^V+v}<6iUjqvj_! zKf8IQxpV*C*IRdbZ#Cb2zkQ{RCye&?-FRzZFvBPIFKgTPzUj5^NFVaONDT#R^y83x zCqgIJQ+34qkhNtx;#~+G*wBvexGLal3nsnAS*yKWQTd$GSa8XX2XEl-{7uW7ySuw` F_%|}P27Ukl literal 0 HcmV?d00001 diff --git a/gdt.c b/gdt.c index 89a3afa..62f9b0d 100644 --- a/gdt.c +++ b/gdt.c @@ -38,8 +38,8 @@ void gdt_flush(void) { "mov %%ax, %%fs\n\t" "mov %%ax, %%gs\n\t" "mov %%ax, %%ss\n\t" - "ljmp $0x08, $flush_cs\n\t" - "flush_cs:\n\t" + "ljmp $0x08, $1f\n\t" + "1:\n\t" : : "m"(gp) : "eax" diff --git a/gdt.o b/gdt.o new file mode 100644 index 0000000000000000000000000000000000000000..caff50efdc47c0021e9b4567de68aed263efd0e8 GIT binary patch literal 1450 zcmZ{kO=uHA6vy8tn-C>#bBGeL!YZp)ENfdV77=W0L6IubR$K8SNt=&WqSj_xYUn{I zwh6&l1TP*0sYgBOp@$w?iwy`;F9DA|mFmT!9>jz7|8}>NEvXOwGr#xd&70ZDWI7}- zv3+zC?J-G~bR#ilm~1rxiAaX#T$Ud~r_$x99*-F@N8WbWN)7XRUnb)mi#i>fA5wH) zAKqF}##qo^b8`ynwH`mQ=~;a}y3lrcjm=vU$KbUi?=`-ajXSP)rRQo_p+gH5y0u^- zt<~n23x=i@ZfNSl_dqi5FCRqW!q-s#_r&UY&R;$PHz$`hbosS~HKf#+RX7tXHM!dI zA<&L>j2{MEzZJQ;Sn}}ZRA`o`CTGylOKwUYl{;9;!{yj!>d=%t{899LnPwVH*ZkzC za9d3GG>`s)+iJS)?EYA$8fiCEayCH4FU9%dN^!0D`P(W&K3bgCAHU;0{U^&WSy|K5 z8yiID+S*R3b)AXPmU{K<$Y9z~`yQwlyRLOLsYAo}ZYTPUqiSQb-lSuDK`siDvYjN2 z`=ot-SJii@C@JW^pivO7=%sNHn-ug!&@(|V z1icdUM$lV9bAsLr`Xp!tv=j2uPZ9ItB(0cgj|Qn%P+E|l984$RvHis_n37U)L+`f& zj&`rj5~<`u?TUF!j9?mr3h_ULMZ_033RTbYAxacU4VgVRm05fP)}iWIoJZt*X?QDc zX%{+vUn=H&W%z&O-m+&a&-ucbt4rrA1#EJ@F1Tc*lu|s?sZs}Nc0wNdesMpNl zcf~p-J8a%wYdtNS&61uNh$M$&cM>?JxDm-Dj7TbG*xumXj1fzxt)XOkBr`zUPW=bo CJ-o&M literal 0 HcmV?d00001 diff --git a/graphics.c b/graphics.c index 7601359..e249d13 100644 --- a/graphics.c +++ b/graphics.c @@ -1,28 +1,31 @@ #include "graphics.h" -#define FONT_TRANSPARENT_COLOR 0xFFFF00FF // Magenta as transparent color -void put_pixel(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t color) { - if (x >= fb->width || y >= fb->height) return; +void put_pixel(FrameBuffer* fb, int32_t x, int32_t y, uint32_t color) { + if (x < 0 || x >= (int32_t)fb->width || y < 0 || y >= (int32_t)fb->height) return; + uint8_t* pixel = (uint8_t*)fb->address + y * fb->pitch + x * fb->bytesPerPixel; if (fb->bitsPerPixel == 24) { - pixel[0] = color & 0xFF; // Blue - pixel[1] = (color >> 8) & 0xFF; // Green - pixel[2] = (color >> 16) & 0xFF; // Red + pixel[0] = color & 0xFF; + pixel[1] = (color >> 8) & 0xFF; + pixel[2] = (color >> 16) & 0xFF; } else if (fb->bitsPerPixel == 32) { *(uint32_t*)pixel = color; } } + void clear_screen(FrameBuffer* fb, uint32_t color) { + // Optimization: We could use memset/memcpy here for speed for (uint32_t y = 0; y < fb->height; y++) { for (uint32_t x = 0; x < fb->width; x++) { put_pixel(fb, x, y, color); } } } -void draw_circle(FrameBuffer* fb, uint32_t xc, uint32_t yc, uint32_t r, uint32_t color) { - int32_t x = (int32_t)r; + +void draw_circle(FrameBuffer* fb, int32_t xc, int32_t yc, int32_t r, uint32_t color) { + int32_t x = r; int32_t y = 0; - int32_t err = 3 - (2 * (int32_t)r); + int32_t err = 3 - (2 * r); while (x >= y) { put_pixel(fb, xc + x, yc + y, color); @@ -43,6 +46,7 @@ void draw_circle(FrameBuffer* fb, uint32_t xc, uint32_t yc, uint32_t r, uint32_t y++; } } + void draw_line(FrameBuffer* fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color) { int32_t dx = (x1 > x0) ? (x1 - x0) : (x0 - x1); int32_t dy = (y1 > y0) ? (y1 - y0) : (y0 - y1); @@ -50,9 +54,7 @@ void draw_line(FrameBuffer* fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t sy = (y0 < y1) ? 1 : -1; int32_t err = dx - dy; while (1) { - if (x0 >= 0 && (uint32_t)x0 < fb->width && y0 >= 0 && (uint32_t)y0 < fb->height) { - put_pixel(fb, (uint32_t)x0, (uint32_t)y0, color); - } + put_pixel(fb, x0, y0, color); if (x0 == x1 && y0 == y1) break; int32_t e2 = 2 * err; if (e2 > -dy) { @@ -65,50 +67,60 @@ void draw_line(FrameBuffer* fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, } } } -void draw_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color) { - if (width == 0 || height == 0) return; - uint32_t x1 = x + width - 1; - uint32_t y1 = y + height - 1; - draw_line(fb, x, y, x1, y, color); // Top - draw_line(fb, x, y1, x1, y1, color); // Bottom - draw_line(fb, x, y, x, y1, color); // Left - draw_line(fb, x1, y, x1, y1, color); // Right +void draw_rectangle(FrameBuffer* fb, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t color) { + if (width <= 0 || height <= 0) return; + int32_t x1 = x + width - 1; + int32_t y1 = y + height - 1; + draw_line(fb, x, y, x1, y, color); + draw_line(fb, x, y1, x1, y1, color); + draw_line(fb, x, y, x, y1, color); + draw_line(fb, x1, y, x1, y1, color); } -void fill_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color) { - for (uint32_t j = y; j < y + height; j++) { - for (uint32_t i = x; i < x + width; i++) { + +void fill_rectangle(FrameBuffer* fb, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t color) { + for (int32_t j = y; j < y + height; j++) { + for (int32_t i = x; i < x + width; i++) { put_pixel(fb, i, j, color); } } } -void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, uint32_t x, uint32_t y, uint32_t color) { + +void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, int32_t x, int32_t y, uint32_t color) { + if (!bmp || !bmp->data) return; for (uint32_t j = 0; j < bmp->height; j++) { for (uint32_t i = 0; i < bmp->width; i++) { - uint8_t pixel = *((uint8_t*)bmp->data + j * bmp->width + i); - if (pixel) { // Assuming non-zero pixel is to be drawn + // [FIX] bmp->data is now a pointer, so we access it as an array + uint8_t pixel = bmp->data[j * bmp->width + i]; + if (pixel) { put_pixel(fb, x + i, y + j, color); } } } } -void draw_char(FrameBuffer* fb, Font* font, char c, uint32_t x, uint32_t y, uint32_t color) { - if (c < 32 || c > 126) return; - Bitmap* bmp = &font->bitmap[c - 32]; - for (uint32_t j = 0; j < bmp->height; j++) { - for (uint32_t i = 0; i < bmp->width; i++) { - uint8_t pixel = *((uint8_t*)bmp->data + j * bmp->width + i); - if (pixel && pixel != FONT_TRANSPARENT_COLOR) { // Skip transparent pixels - put_pixel(fb, x + i, y + j, color); + +// [FIX] Completely rewritten to match the font.c raw array format +void draw_char(FrameBuffer* fb, Font* font, char c, int32_t x, int32_t y, uint32_t color) { + if (!font || !font->bitmap) return; + + // Get the pointer to the 16 bytes for this character + const uint8_t* glyph = font->bitmap[(unsigned char)c]; + + for (uint32_t cy = 0; cy < font->char_height; cy++) { + uint8_t row = glyph[cy]; + for (uint32_t cx = 0; cx < font->char_width; cx++) { + // Check the bit at this position (Bit 7 is leftmost) + if ((row >> (7 - cx)) & 1) { + put_pixel(fb, x + cx, y + cy, color); } } } } -void draw_string(FrameBuffer* fb, Font* font, const char* str, uint32_t x, uint32_t y, uint32_t color) { + +void draw_string(FrameBuffer* fb, Font* font, const char* str, int32_t x, int32_t y, uint32_t color) { while (*str) { draw_char(fb, font, *str, x, y, color); x += font->char_width; str++; } -} -#undef FONT_TRANSPARENT_COLOR \ No newline at end of file +} \ No newline at end of file diff --git a/graphics.h b/graphics.h index c339dac..99beb9a 100644 --- a/graphics.h +++ b/graphics.h @@ -24,29 +24,30 @@ typedef struct __attribute__((packed)){ } VbeModeInfo; typedef struct{ void* address; - uint32_t width; - uint32_t height; - uint32_t pitch; - uint8_t bitsPerPixel; - uint8_t bytesPerPixel; + uint32_t width; + uint32_t height; + uint32_t pitch; + uint8_t bitsPerPixel; + uint8_t bytesPerPixel; } FrameBuffer; typedef struct { uint32_t width; uint32_t height; - uint8_t data; -}Bitmap; + uint8_t* data; +} Bitmap; typedef struct { - Bitmap* bitmap; uint32_t char_width; uint32_t char_height; -}Font; + const uint8_t (*bitmap)[16]; +} Font; void clear_screen(FrameBuffer* fb, uint32_t color); -void put_pixel(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t color); -void draw_line(FrameBuffer* fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t color); -void draw_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color); -void fill_rectangle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color); -void draw_circle(FrameBuffer* fb, uint32_t x, uint32_t y, uint32_t radius, uint32_t color); -void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, uint32_t x, uint32_t y, uint32_t color); -void draw_char(FrameBuffer* fb, Font* font, char c, uint32_t x, uint32_t y, uint32_t color); -void draw_string(FrameBuffer* fb, Font* font, const char* str, uint32_t x, uint32_t y, uint32_t color); +void put_pixel(FrameBuffer* fb, int32_t x, int32_t y, uint32_t color); +void draw_line(FrameBuffer* fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color); +void draw_rectangle(FrameBuffer* fb, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t color); +void fill_rectangle(FrameBuffer* fb, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t color); +void draw_circle(FrameBuffer* fb, int32_t x, int32_t y, int32_t radius, uint32_t color); +void draw_bitmap(FrameBuffer* fb, Bitmap* bmp, int32_t x, int32_t y, uint32_t color); +void draw_char(FrameBuffer* fb, Font* font, char c, int32_t x, int32_t y, uint32_t color); +void draw_string(FrameBuffer* fb, Font* font, const char* str, int32_t x, int32_t y, uint32_t color); + #endif \ No newline at end of file diff --git a/graphics.o b/graphics.o new file mode 100644 index 0000000000000000000000000000000000000000..0215d05e12cfae50b30b4072b81c87c736695031 GIT binary patch literal 3722 zcmZ`+ZERat89vv(%kE;!*PT3MgwPsy0Ae6jniPIio-_n<>a0$0nUmb1;w25QhbZ)pN&?1dJC1(%rkY`%#^2`UqywxIS_dCbGaH~7UzfcCN z^e*nw+^^>|>eCD&T=IL^n7!kSYwpRHE$06BUOCW_`nL$ETOZ*by;Vx*7J}lQ> zEP2ZIFQ%>twT0AOA=7!LI`BaLaRZ=QC+7%w7*T7|RBjg*H4hi=XkjklNW^r4_7o01 zTwaDXVPKnpFrY<%Bfy1$BPYY$RrscfGh_i*yQIw<0WdLybr&8lV<5{@mQ`ECi3BMm z$y2!Zz|=-+Oev%%!WGE!5UTLk4TvIk3E?rc5#n7F;ei%cS&M;zC534^gKIcbR?f&< z*icZ-GoD_M&&|WqOy~Pmh#Ufz`5Tt0xf&x!(`Njgs3i_jHPGt~bn^PKUC2az?TtW$ z`{k*xBg9bRzY<1hkq|s3de+WsA}>8ddDd>!fx&>EyGeC6Usq;W#sG|Xh}04GdvL*9 zd-L<#s7tXFH0mABW;{&0ROjV^TXN(QD#9*YC-QpWe#TpGZb{ZY7R**O?p%cbaC(Kb8`009Xcp^CW@NABb2b=v_7d7$Cupd+v7{hpbI>Wn$4`M zm3j=qc{$xrhIVm3iIUTYu}aN3jexC$fm~S^hT>D$iBGTkO#xctchPE`!>va7Jt&^N zi+gR;ijyx{NjDBSLXNQb>*rLF<8u*9?DNp@` z{P9}TpUG2aK?35ps+?>Usi~oUGH)^M=4|0f?FtULAs?MJ5@->}UeJ~%t`0T_4oYJo zz0EFXPoSH9K+UWO+G(xU?A*-#9?CuSGr#WTT02{xf9hwKPoGcag&=BkWI8oxFE=yO ze##v&#=$9Paa$+bEv0K4^XG(5HR;dPALs|9^n$ADd&P84J*ihUEN|$aNNRnRR!{i zOSt91F){J`m5N>OpBaA_V(&F?5=x8;dzAmuEjX@oca=~1j^ zKNai3yiu4h8xbuT9U76rP{pw+gr(d zTHcC#He3is#nFF_k8qIU`QJKNS+z8qYx!IJA`C@0(&Ll6FD1oTA!mAlb>Ep zGjuy3RNEP}B+ldhJ=8-SAC6Q`FV^ z`gB8=AF1&|x)A{R&s7sSb$5K)xR?>6@a?I~lmdFgxX{q(u85kK7k+`e2D~*mksJIl zHRm=JPn+X~*4A$+HTz?4HF}kn!QMVqIr6sB-tk(;Ze<|x=80I3TB|fX>)Y+CXUv75 z(-2PWXTpdie9bP3lV~dn_B@y(W)~)Fc1S6UrKLLW5Wi#Vz%OGVY&T&Z#mr+8CT(eU z*nenkb~w+9%??-UkyeM>@~dixt2ys*HeYtwo3A*e=1UH7ug%~e2b&-IPGfGvAF?Ke z&HR9q{v757{7*W&JwLZ{VG9GAZ7+kDfiDbS=zX${e!u09Td=p;TDLNaZ0dwej=!Hb zwwI|`-rYjxi#FB>o}YnVtYYk^+w*hF+0EKX_lMwp2fR<sElLT5_>)g_@{Pa}`R2T_*0;3ia~}^-+a#!44DWi}&`$z)$1hGGoVt zV~Os8&~^LCDHuH=gz2-;7!P%l>U({s0R% zW2#rgur^RlP`w#ruV4;>Qcx+IF^&r61W_<=GsaoL41xOfmYByYm@}Yq$n0i0CS>i` z5rxkxxK|x6OIiD61owd{AFO$-{VK9mR=?FX>y(D$w^3eFLqI zcR>0Q^tr}QojS#QvE$KrqWffwMF$4e=s@pqtdB)|`eNOQXtE~}i}kbU(M0!9w5K +#include #define HEAP_ALIGNMENT 4 #define HEAP_MAGIC 0x12345678 diff --git a/heap.o b/heap.o new file mode 100644 index 0000000000000000000000000000000000000000..7e3d6943678804a89b37559252f260149fba9e85 GIT binary patch literal 1332 zcmaJ>%}*0i5Pz?`!Y*211-~MPJv0WCEEFLD4`xeAB#Ne`RY4)8gX&w$}kXhN8ZD{(9I&r?L51tF2iR1!%2pRx+Pj_&Gc zJGf)^ZP+czM!5*avcpNj^@P5e`F1cuxzl zun9`*_qvm;n{p`_yuh~(OG~}&e1A5XQuxFQe>E~1>EajD3$xOs(#HFHgf5}8eD@H- zxnYFwGWhfnnqGr_H^M$!K*^qaL5c97P=W?PpMs)5J)?R&<8>SLbpK(`H8AKTgrlIl zpc<&nc}Q{`xb>hl=!AoAI%vv4j~w*TLA5ZGRhxDY57|1Co;^mtY;_4n23!&>aFux6-D~GG>gzb^{M`7~j ztqs^=Gz&mTlc9XMTn-7+OiWJ4=Oh#(`;H~&lM0H-$#h1EWu)mjX&ziNlUkU(W5aj~ M92?7NNjkXUZ(*w5u>b%7 literal 0 HcmV?d00001 diff --git a/idt.c b/idt.c index 5a81cb4..06ee6a3 100644 --- a/idt.c +++ b/idt.c @@ -1,6 +1,8 @@ #include "idt.h" #include "vga.h" #include "syscall.h" + +// [FIX] Use aligned definitions if possible, but packed struct is fine. static struct idt_entry idt[256]; static struct idt_ptr ip; @@ -13,40 +15,18 @@ static inline uint8_t inb(uint16_t port) { asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } + static const char *exception_messages[] = { - "Division By Zero", - "Debug", - "Non Maskable Interrupt", - "Breakpoint", - "Into Detected Overflow", - "Out of Bounds", - "Invalid Opcode", - "No Coprocessor", - "Double Fault", - "Coprocessor Segment Overrun", - "Bad TSS", - "Segment Not Present", - "Stack Fault", - "General Protection Fault", - "Page Fault", - "Unknown Interrupt", - "Coprocessor Fault", - "Alignment Check", - "Machine Check", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved" + "Division By Zero", "Debug", "Non Maskable Interrupt", "Breakpoint", + "Into Detected Overflow", "Out of Bounds", "Invalid Opcode", "No Coprocessor", + "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present", + "Stack Fault", "General Protection Fault", "Page Fault", "Unknown Interrupt", + "Coprocessor Fault", "Alignment Check", "Machine Check", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved" }; + void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt[num].base_lo = base & 0xFFFF; idt[num].base_hi = (base >> 16) & 0xFFFF; @@ -54,52 +34,37 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt[num].always0 = 0; idt[num].flags = flags; } + void isr_handler(registers_t *r) { - // Validate register structure pointer - if (r == NULL) { - vga_print_string("Critical error: NULL register pointer in ISR!\n"); - asm volatile("cli"); - for(;;) { asm volatile("hlt"); } + if (r == NULL) return; + + // [FIX] Handle System Call (Interrupt 128 / 0x80) + if (r->int_no == 128) { + syscall_handler(r); + return; } vga_print_string("Received interrupt: "); vga_print_dec(r->int_no); - vga_print_string(" - "); + vga_print_string("\n"); if (r->int_no < 32) { - // Handle CPU exceptions if (r->int_no < sizeof(exception_messages) / sizeof(exception_messages[0])) { vga_print_string(exception_messages[r->int_no]); } else { vga_print_string("Unknown Exception"); } - vga_print_string("\nEIP: 0x"); - vga_print_hex(r->eip); - vga_print_string(" CS: 0x"); - vga_print_hex(r->cs); - vga_print_string(" EFLAGS: 0x"); - vga_print_hex(r->eflags); - vga_print_string(" ESP: 0x"); - vga_print_hex(r->esp); - - // Additional debug information for certain exceptions - if (r->int_no == 13) { // General Protection Fault - vga_print_string("\nError code: 0x"); - vga_print_hex(r->err_code); - } - - vga_print_string("\nSystem halted due to exception!\n"); + + // Loop forever on exception asm volatile("cli"); - for(;;) { - asm volatile("hlt"); - } + for(;;) { asm volatile("hlt"); } } } static void (*irq_routines[16])(registers_t *r); void irq_install_handler(int irq, void (*handler)(registers_t *r)) { - if (irq >= 0 && irq < 16 && handler != NULL) { + if (irq >= 0 && irq < 16) { irq_routines[irq] = handler; } } @@ -111,33 +76,15 @@ void irq_uninstall_handler(int irq) { } void irq_handler(registers_t *r) { - // Validate register structure pointer - if (r == NULL) { - return; - } + if (r->int_no < 32 || r->int_no > 47) return; - // Validate interrupt number range for IRQs - if (r->int_no < 32 || r->int_no > 47) { - return; + void (*handler)(registers_t *r) = irq_routines[r->int_no - 32]; + if (handler) { + handler(r); } - int irq = r->int_no - 32; - - // Double-check IRQ bounds - if (irq >= 0 && irq < 16) { - void (*handler)(registers_t *r) = irq_routines[irq]; - if (handler != NULL) { - // Call the registered handler - handler(r); - } - } - - // Send End of Interrupt signal to PICs - if (r->int_no >= 40) { - // Send reset signal to slave PIC - outb(0xA0, 0x20); - } - // Send reset signal to master PIC + // EOI + if (r->int_no >= 40) outb(0xA0, 0x20); outb(0x20, 0x20); } @@ -145,9 +92,8 @@ void idt_install(void) { ip.limit = sizeof(struct idt_entry) * 256 - 1; ip.base = (uint32_t)&idt; - for (int i = 0; i < 256; i++) { - idt_set_gate(i, 0, 0, 0); - } + // Zero out IDT + for(int i=0; i<256; i++) idt_set_gate(i, 0, 0, 0); idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E); idt_set_gate(1, (uint32_t)isr1, 0x08, 0x8E); @@ -177,21 +123,17 @@ void idt_install(void) { idt_set_gate(25, (uint32_t)isr25, 0x08, 0x8E); idt_set_gate(26, (uint32_t)isr26, 0x08, 0x8E); idt_set_gate(27, (uint32_t)isr27, 0x08, 0x8E); - idt_set_gate(28, (uint32_t)isr28, 0x08, 0x8E); + idt_set_gate(28, (uint32_t)isr28, 0x08, 0x8E); // Now defined in header idt_set_gate(29, (uint32_t)isr29, 0x08, 0x8E); idt_set_gate(30, (uint32_t)isr30, 0x08, 0x8E); idt_set_gate(31, (uint32_t)isr31, 0x08, 0x8E); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); + // Remap PIC + outb(0x20, 0x11); outb(0xA0, 0x11); + outb(0x21, 0x20); outb(0xA1, 0x28); + outb(0x21, 0x04); outb(0xA1, 0x02); + outb(0x21, 0x01); outb(0xA1, 0x01); + outb(0x21, 0x0); outb(0xA1, 0x0); idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E); idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E); @@ -209,61 +151,19 @@ void idt_install(void) { idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E); idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E); idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E); - idt_set_gate(128,(uint32_t)isr128,0x08,0xEE); + + // Syscall + idt_set_gate(128, (uint32_t)isr128, 0x08, 0xEE); // Ring 3 accessible + asm volatile("lidt %0" : : "m"(ip)); asm volatile("sti"); } -uint32_t inl(uint16_t port) { - uint32_t ret; - asm volatile("inl %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} -void outl(uint16_t port, uint32_t val) { - asm volatile("outl %0, %1" : : "a"(val), "Nd"(port)); -} void page_fault_handler(registers_t *r) { - // Function is called when there is a page fault - // The faulting address is stored in the CR2 register uint32_t faulting_address; asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); - - // The error code gives us the details about the fault - int present = !(r->err_code & 0x1); // Page is not present - int rw = r->err_code & 0x2; // Write operation? - int us = r->err_code & 0x4; // Were we in user-mode? - int reserved = r->err_code & 0x8; // Overwritten reserved bits? - int id = (r->err_code & 0x10) >> 4; // Instruction fetch (if NX enabled) - int pk = (r->err_code & 0x20) >> 5; // Protection key violation (if PKU enabled) - int ss = (r->err_code & 0x40) >> 6; // Shadow stack violation (Intel CET) - int sgx = (r->err_code & 0x80) >> 7; // SGX access violation (if SGX enabled) - - // Display detailed page fault information - vga_print_string("\n\nPAGE FAULT!\n"); - vga_print_string("Faulting address: 0x"); + vga_print_string("Page Fault at 0x"); vga_print_hex(faulting_address); - vga_print_string("\nError code: 0x"); - vga_print_hex(r->err_code); - vga_print_string("\nEIP: 0x"); - vga_print_hex(r->eip); - - vga_print_string("\nFault type: "); - if (!present) vga_print_string("Page not present "); - if (rw) vga_print_string("Write operation "); - if (us) vga_print_string("User mode "); - if (reserved) vga_print_string("Reserved bits overwritten "); - if (id) vga_print_string("Instruction fetch "); - if (pk) vga_print_string("Protection key violation "); - if (ss) vga_print_string("Shadow stack violation "); - if (sgx) vga_print_string("SGX access violation "); - - vga_print_string("\nSystem halted due to page fault!\n"); - - // Prevent unused variable warnings - (void)id; (void)pk; (void)ss; (void)sgx; - - asm volatile("cli"); - for(;;) { - asm volatile("hlt"); - } + vga_print_string("\n"); + for(;;) asm volatile("hlt"); } \ No newline at end of file diff --git a/idt.h b/idt.h index 397f194..b45002f 100644 --- a/idt.h +++ b/idt.h @@ -79,6 +79,7 @@ extern void isr28(void); extern void isr29(void); extern void isr30(void); extern void isr31(void); +extern void isr128(void); uint32_t inl(uint16_t port); void outl(uint16_t port, uint32_t val); #endif \ No newline at end of file diff --git a/idt.o b/idt.o new file mode 100644 index 0000000000000000000000000000000000000000..255ed2dc2aeaddcef4ae4e3964fe915c67e03c4f GIT binary patch literal 7524 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 IH|8ewKPio&;{X5v literal 0 HcmV?d00001 diff --git a/kernel.c b/kernel.c index df37c02..2ebc1fc 100644 --- a/kernel.c +++ b/kernel.c @@ -19,7 +19,10 @@ #include "window.h" #include "mouse.h" #include "cursor.h" +#include "heap.h" +#include "console.h" #include "dirty_rect.h" +#define VBE_INFO_PTR ((vbe_mode_info_t*)0x8000) void counter_task(){ int i=0; while(1){ @@ -59,16 +62,30 @@ typedef struct { extern vbe_mode_info_t vbe_mode_info; void kernel_main(void) { + gdt_install(); + idt_install(); + pmm_init(128 * 1024 * 1024); + heap_init(0x00400000, 16 * 1024 * 1024); // 16 MB heap at 4 MB vga_init(); vga_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK)); vga_print_string("SimpleOS Kernel v1.0 [SECURED]\n"); vga_print_string("===============================\n\n"); - gdt_install(); - idt_install(); syscalls_install(); paging_install(); - pmm_init(128 * 1024 * 1024); + console_init(); + FrameBuffer fb; + fb.address=(void*)vbe_mode_info.physbase; + fb.width=vbe_mode_info.resolution_x; + fb.height=vbe_mode_info.resolution_y; + fb.pitch=vbe_mode_info.pitch; + fb.bitsPerPixel=vbe_mode_info.bitsPerPixel; + fb.bytesPerPixel = vbe_mode_info.bitsPerPixel / 8; + Font my_font; + my_font.char_width=8; + my_font.char_height=16; + my_font.bitmap=NULL; // Assume a function to load a bitmap font + console_init_graphics(&fb,&my_font); asm volatile("sti"); keyboard_install(); timer_install(); @@ -85,18 +102,6 @@ void kernel_main(void) { vga_print_string("\nKernel initialization complete!\n"); vga_print_string("Security features: Buffer overflow protection, bounds checking\n"); vga_print_string("Starting shell...\n\n"); - FrameBuffer fb; - fb.address=(void*)vbe_mode_info.physbase; - fb.width=vbe_mode_info.resolution_x; - fb.height=vbe_mode_info.resolution_y; - fb.pitch=vbe_mode_info.pitch; - fb.bitsPerPixel=vbe_mode_info.bitsPerPixel; - fb.bytesPerPixel = vbe_mode_info.bitsPerPixel / 8; - Font my_font; - my_font.char_width=8; - my_font.char_height=16; - my_font.bitmap=NULL; // Assume a function to load a bitmap font - if (fb.bitsPerPixel != 24) { vga_print_string("Error: Graphics mode is not 24-bit color depth!\n"); for(;;) { asm volatile("cli; hlt"); } @@ -139,56 +144,41 @@ void kernel_main(void) { #define CURSOR_TRAIL_LENGTH 8 struct { int32_t x, y; } cursor_history[CURSOR_TRAIL_LENGTH] = {0}; int history_index = 0; - uint8_t last_buttons = 0; int32_t last_x = -1, last_y = -1; - - // Initial full-screen draw dirty_rect_add(0, 0, fb.width, fb.height); while(1) { - // --- Input and State Update Phase --- bool mouse_moved = (mouse_x != last_x || mouse_y != last_y); bool buttons_changed = (mouse_buttons != last_buttons); if (mouse_moved || buttons_changed) { - // Invalidate old cursor position - dirty_rect_add(last_x, last_y, 16, 16); // Assuming cursor size - - // Handle window manager logic (dragging, etc.) + dirty_rect_add(last_x, last_y, 16, 16); window_manager_handle_mouse(&window_list_head, &window_list_tail, mouse_x, mouse_y, mouse_buttons, last_buttons); - - // Invalidate new cursor position dirty_rect_add(mouse_x, mouse_y, 16, 16); last_x = mouse_x; last_y = mouse_y; last_buttons = mouse_buttons; } - - // --- Drawing Phase --- int dirty_count; const Rect* rects = dirty_rect_get_all(&dirty_count); if (dirty_count > 0) { - // For each dirty rectangle, redraw all windows that intersect with it for (int i = 0; i < dirty_count; i++) { const Rect* dirty = &rects[i]; Window* current = window_list_head; while (current) { - // Simple intersection check if (!(current->x > dirty->x + dirty->width || current->x + current->width < dirty->x || current->y > dirty->y + dirty->height || current->y + current->height < dirty->y)) { - window_draw(current, &fb); // In a more advanced system, we'd clip the drawing. + window_draw(current, &fb); } current = current->next; } } - // After drawing, clear the list for the next frame. dirty_rect_init(); } - // Always draw the cursor on top of the final scene cursor_update(&fb, mouse_x, mouse_y); asm volatile("hlt"); diff --git a/paging.h b/paging.h index 5d6857b..caa976b 100644 --- a/paging.h +++ b/paging.h @@ -1,9 +1,7 @@ -#ifndef PAGING_H +/* #ifndef PAGING_H #define PAGING_H #include -#include "idt.h" //This is for interrupt handling - -// Paging memory layout constants +#include "idt.h" #define PAGING_STRUCTURES_START ((uint32_t)&page_directory) #define PAGING_STRUCTURES_SIZE (8192) // 8KB for directory + table extern pt_entry_t page_directory[1024]; @@ -27,4 +25,17 @@ typedef struct pt_entry{ void paging_install(void); uint32_t paging_get_reserved_start(void); uint32_t paging_get_reserved_end(void); +#endif */ + +#ifndef PAGING_H +#define PAGING_H + +#include +typedef uint32_t pt_entry_t; + +void paging_install(void); +void map_page(void *physaddr, void *virtualaddr, unsigned int flags); +extern pt_entry_t page_directory[1024]; +extern pt_entry_t first_page_table[1024]; + #endif diff --git a/syscall.c b/syscall.c index b1cc7df..00aff34 100644 --- a/syscall.c +++ b/syscall.c @@ -1,5 +1,7 @@ #include "syscall.h" #include "vga.h" +void syscall_install(void){ + vga_print_string("Syscall Interface Installed, Simple OS WORKING\n");} void syscall_handler(registers_t *r){ if (r->eax==0){ vga_print_string("SYSTEM CALL RECEIVED!, SIMPLE OS WORKING\n"); diff --git a/syscall.h b/syscall.h index c1bb157..79ff222 100644 --- a/syscall.h +++ b/syscall.h @@ -4,5 +4,6 @@ #include "idt.h" void syscalls_install(void); +void syscall_handler(registers_t *r); #endif \ No newline at end of file diff --git a/task.h b/task.h index da59e4e..560f46e 100644 --- a/task.h +++ b/task.h @@ -2,6 +2,8 @@ #define TASK_H #include #include "idt.h" +#include "sync.h" +#include "spinlock.h" typedef enum { TASK_RUNNING, TASK_READY, diff --git a/widget.h b/widget.h index 8af0dc8..e91a3a1 100644 --- a/widget.h +++ b/widget.h @@ -1,6 +1,7 @@ #ifndef WIDGET_H #define WIDGET_H #include "graphics.h" +#include "font.h" #include struct Widget; typedef enum { @@ -73,7 +74,11 @@ typedef struct{ } ButtonData; //Below are the constructors. Widget* create_label(int x,int y,int width,int height,char* text,uint32_t color); -Widget* create_button(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width,uint32_t base_color,int base_width,uint32_t text_color,uint32_t press_color,uint32_t press_border,uint32_t hover_color,uint32_t hover_border); -Widget* create_checkbox(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width); +//Widget* create_button(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width,uint32_t base_color,int base_width,uint32_t text_color,uint32_t press_color,uint32_t press_border,uint32_t hover_color,uint32_t hover_border); +Widget* create_button(int x, int y, int w, int h, char* text, + uint32_t text_color, uint32_t base_color, uint32_t border_color); + +void widget_draw(Widget* widget, FrameBuffer* fb); +//Widget* create_checkbox(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width); #endif \ No newline at end of file From b2f1450e46c45184567771eb2d9066a396571c6b Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Sat, 13 Dec 2025 21:57:48 +0530 Subject: [PATCH 16/18] Add files via upload --- boot.asm | 2 +- boot.bin | Bin 512 -> 512 bytes build_iso.sh | 24 ++++++++++ create_iso.sh | 60 ++++++++++++++++++++++++ floppy.img | Bin 0 -> 1474560 bytes font.h | 1 + idt.c | 1 + idt.h | 2 - interrupt.asm | 119 ++++++++++++++++++++++++----------------------- interrupt.o | Bin 0 -> 1716 bytes io.h | 29 ++++++++++++ kernel.bin | Bin 0 -> 1115400 bytes kernel.c | 16 +++---- kernel.elf | Bin 0 -> 55593 bytes kernel.o | Bin 0 -> 5458 bytes kernel_entry.asm | 8 ++++ kernel_entry.o | Bin 0 -> 238 bytes keyboard.c | 12 +---- keyboard.o | Bin 0 -> 2358 bytes lib.c | 41 ++++++++++++++++ lib.o | Bin 0 -> 1436 bytes mouse.c | 37 ++------------- mouse.o | Bin 0 -> 1464 bytes mutex.c | 2 - mutex.o | Bin 0 -> 1465 bytes nic.c | 64 +++++++++++++++++++++++++ nic.h | 6 +++ nic.o | Bin 0 -> 1696 bytes os-image.bin | Bin 0 -> 1115912 bytes paging.c | 27 +++-------- paging.o | Bin 0 -> 1181 bytes pci.c | 3 +- pci.h | 3 +- pci.o | Bin 0 -> 1314 bytes pmm.c | 33 ++++++++++++- pmm.h | 1 + pmm.o | Bin 0 -> 2855 bytes run.sh | 38 +++++++++++++++ shell.c | 11 +---- shell.h | 10 ---- shell.o | Bin 0 -> 4340 bytes spinlock.o | Bin 0 -> 914 bytes sync.h | 6 +-- syscall.o | Bin 0 -> 1028 bytes task.c | 7 ++- task.h | 2 +- task.o | Bin 0 -> 2220 bytes timer.c | 1 + timer.o | Bin 0 -> 1034 bytes vga.o | Bin 0 -> 3086 bytes widget.c | 84 +++++++++++++++++++++------------ widget.h | 24 +++++++--- widget.o | Bin 0 -> 6580 bytes window.c | 20 ++------ window.h | 1 + window.o | Bin 0 -> 6632 bytes 56 files changed, 480 insertions(+), 215 deletions(-) create mode 100644 build_iso.sh create mode 100644 create_iso.sh create mode 100644 floppy.img create mode 100644 interrupt.o create mode 100644 io.h create mode 100644 kernel.bin create mode 100644 kernel.elf create mode 100644 kernel.o create mode 100644 kernel_entry.asm create mode 100644 kernel_entry.o create mode 100644 keyboard.o create mode 100644 lib.c create mode 100644 lib.o create mode 100644 mouse.o create mode 100644 mutex.o create mode 100644 nic.c create mode 100644 nic.h create mode 100644 nic.o create mode 100644 os-image.bin create mode 100644 paging.o create mode 100644 pci.o create mode 100644 pmm.o create mode 100644 run.sh create mode 100644 shell.o create mode 100644 spinlock.o create mode 100644 syscall.o create mode 100644 task.o create mode 100644 timer.o create mode 100644 vga.o create mode 100644 widget.o create mode 100644 window.o diff --git a/boot.asm b/boot.asm index f58497c..ce09ab3 100644 --- a/boot.asm +++ b/boot.asm @@ -17,7 +17,7 @@ TARGET_BPP equ 32 ; Kernel placement KERNEL_TEMP_ADDR equ 0x1000 ; Segment 0x1000 (Physical 0x10000) KERNEL_TARGET_ADDR equ 0x100000 ; 1MB -SECTORS_TO_READ equ 60 ; Read 30KB +SECTORS_TO_READ equ 100 ; Read 50KB start: jmp 0:init_segments ; Far jump to normalize CS diff --git a/boot.bin b/boot.bin index afb5ca8fe2e9935d72dbb5fb4b90a698f8ae2b92..a7532c8be10f801f250d6e0a4d8174d5bf134a68 100644 GIT binary patch delta 17 YcmZo*X<(T!oiSzN3|B^@jrWuo0X07b=l}o! delta 17 YcmZo*X<(T!ozZ6E3|B_EjrWuo0W(VltN;K2 diff --git a/build_iso.sh b/build_iso.sh new file mode 100644 index 0000000..0c8476b --- /dev/null +++ b/build_iso.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Check if the raw OS image exists +if [ ! -f os-image.bin ]; then + echo "Error: os-image.bin not found. Run the build commands first." + exit 1 +fi + +# 1. Create a blank 1.44MB floppy image (1474560 bytes) +dd if=/dev/zero of=floppy.img bs=1024 count=1440 + +# 2. Write the OS image (bootloader + kernel) to the floppy image +# conv=notrunc ensures we overwrite the start without truncating the file +dd if=os-image.bin of=floppy.img conv=notrunc + +# 3. Create the ISO directory structure +mkdir -p iso_root +cp floppy.img iso_root/ + +# 4. Generate the ISO using mkisofs (Floppy Emulation Mode) +# -b specifies the boot image. Since it is 1.44MB, mkisofs enables floppy emulation. +mkisofs -o simpleos.iso -b floppy.img iso_root/ + +echo "Done! You can now boot simpleos.iso in a VM." \ No newline at end of file diff --git a/create_iso.sh b/create_iso.sh new file mode 100644 index 0000000..abf35f9 --- /dev/null +++ b/create_iso.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Stop on error +set -e + +echo "Assembling entry point..." +nasm -f win32 kernel_entry.asm -o kernel_entry.o + +echo "Assembling bootloader..." +nasm -f bin boot.asm -o boot.bin + +echo "Assembling interrupts..." +nasm -f win32 interrupt.asm -o interrupt.o + +echo "Compiling C sources..." +# Note: nic.c is used +C_SOURCES="console.c cursor.c dirty_rect.c font.c gdt.c graphics.c heap.c idt.c kernel.c keyboard.c mouse.c mutex.c paging.c pci.c pmm.c shell.c spinlock.c syscall.c task.c timer.c vga.c widget.c window.c nic.c lib.c" + +OBJ_FILES="kernel_entry.o interrupt.o" + +for file in $C_SOURCES; do + obj="${file%.*}.o" + i686-w64-mingw32-gcc -m32 -ffreestanding -O2 -Wall -Wextra -I. -c "$file" -o "$obj" + OBJ_FILES="$OBJ_FILES $obj" +done + +echo "Linking kernel..." +# Linking kernel_entry.o FIRST is crucial so it ends up at 0x100000 +# -Wl,--image-base,0 fixes "section below image base" error on MinGW +i686-w64-mingw32-gcc -Wl,--image-base,0 -Ttext 0x100000 -o kernel.elf -ffreestanding -O2 -nostdlib $OBJ_FILES -lgcc + +echo "Extracting binary..." +# Try to find the correct objcopy +if command -v i686-w64-mingw32-objcopy &> /dev/null; then + i686-w64-mingw32-objcopy -O binary kernel.elf kernel.bin +else + objcopy -O binary kernel.elf kernel.bin +fi + +echo "Creating OS image..." +cat boot.bin kernel.bin > os-image.bin + +echo "Creating Floppy Image..." +# Create 1.44MB floppy image +dd if=/dev/zero of=floppy.img bs=1024 count=1440 2>/dev/null +dd if=os-image.bin of=floppy.img conv=notrunc 2>/dev/null + +echo "Creating ISO..." +mkdir -p iso_root +cp floppy.img iso_root/ + +# Generate ISO with floppy emulation +if command -v mkisofs &> /dev/null; then + mkisofs -quiet -o simpleos.iso -b floppy.img iso_root/ + echo "Build Complete: simpleos.iso" +else + echo "Warning: 'mkisofs' not found. Skipping ISO creation." + echo "You can use 'floppy.img' directly in VirtualBox (Floppy Controller) or QEMU." + echo "Build Complete: floppy.img" +fi \ No newline at end of file diff --git a/floppy.img b/floppy.img new file mode 100644 index 0000000000000000000000000000000000000000..c2c65f0fbba8c5ef11f7cbdd180f8c695ee18f06 GIT binary patch literal 1474560 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 z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs N0RjXF5cod={{^AeAtL|) literal 0 HcmV?d00001 diff --git a/font.h b/font.h index 88ba8be..f2dfd2d 100644 --- a/font.h +++ b/font.h @@ -1,5 +1,6 @@ #ifndef FONT_H #define FONT_H #include +#include "graphics.h" extern const uint8_t font[256][16]; #endif \ No newline at end of file diff --git a/idt.c b/idt.c index 06ee6a3..42eafcf 100644 --- a/idt.c +++ b/idt.c @@ -160,6 +160,7 @@ void idt_install(void) { } void page_fault_handler(registers_t *r) { + (void)r; uint32_t faulting_address; asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); vga_print_string("Page Fault at 0x"); diff --git a/idt.h b/idt.h index b45002f..10984c9 100644 --- a/idt.h +++ b/idt.h @@ -80,6 +80,4 @@ extern void isr29(void); extern void isr30(void); extern void isr31(void); extern void isr128(void); -uint32_t inl(uint16_t port); -void outl(uint16_t port, uint32_t val); #endif \ No newline at end of file diff --git a/interrupt.asm b/interrupt.asm index cd5de50..6a2e8e5 100644 --- a/interrupt.asm +++ b/interrupt.asm @@ -1,74 +1,77 @@ section .text -global isr0 -global isr1 -global isr2 -global isr3 -global isr4 -global isr5 -global isr6 -global isr7 -global isr8 -global isr9 -global isr10 -global isr11 -global isr12 -global isr13 -global isr14 -global isr15 -global isr16 -global isr17 -global isr18 -global isr19 -global isr20 -global isr21 -global isr22 -global isr23 -global isr24 -global isr25 -global isr26 -global isr27 -global isr28 -global isr29 -global isr30 -global isr31 +global _isr0 +global _isr1 +global _isr2 +global _isr3 +global _isr4 +global _isr5 +global _isr6 +global _isr7 +global _isr8 +global _isr9 +global _isr10 +global _isr11 +global _isr12 +global _isr13 +global _isr14 +global _isr15 +global _isr16 +global _isr17 +global _isr18 +global _isr19 +global _isr20 +global _isr21 +global _isr22 +global _isr23 +global _isr24 +global _isr25 +global _isr26 +global _isr27 +global _isr28 +global _isr29 +global _isr30 +global _isr31 -global irq0 -global irq1 -global irq2 -global irq3 -global irq4 -global irq5 -global irq6 -global irq7 -global irq8 -global irq9 -global irq10 -global irq11 -global irq12 -global irq13 -global irq14 -global irq15 -global isr128 -extern isr_handler -extern irq_handler +global _irq0 +global _irq1 +global _irq2 +global _irq3 +global _irq4 +global _irq5 +global _irq6 +global _irq7 +global _irq8 +global _irq9 +global _irq10 +global _irq11 +global _irq12 +global _irq13 +global _irq14 +global _irq15 +global _isr128 +extern _isr_handler +extern _irq_handler %macro isr_no_error 1 -isr%1: +global _isr%1 +_isr%1: cli push byte 0 - push byte %1 + push dword %1 jmp isr_common_stub %endmacro %macro isr_error 1 -isr%1: +global _isr%1 +_isr%1: cli - push byte %1 + push dword %1 jmp isr_common_stub %endmacro %macro irq_stub 2 -irq%1: +global _irq%1 +_irq%1: cli push byte 0 push byte %2 @@ -136,7 +139,7 @@ isr_common_stub: mov fs, ax mov gs, ax - call isr_handler + call _isr_handler pop eax mov ds, ax @@ -160,7 +163,7 @@ irq_common_stub: mov fs, ax mov gs, ax - call irq_handler + call _irq_handler pop eax mov ds, ax diff --git a/interrupt.o b/interrupt.o new file mode 100644 index 0000000000000000000000000000000000000000..f4e37f2b2428700de7cbbb8ae4173d132569b68c GIT binary patch literal 1716 zcma)+OGuPq6o$VUFPT|tnPnHV%reu-@zPbL7KMwVAt+oFdOI$8p6PHI9 z#pP2%+!E@uu7H9VIbvd!&f+3ucUsdZ1W>~N2>)VZB3JKaMp z_3nO_2Dh2T=hn0Aa%;MyH>U&9*Ci%Boqm`8mY$ix`%KrrDm3=KU~cL^CQVJ^7tO=c zGBXR8Z=Ek18;J0Jc>c^A)8~l|r6P_qaxUcyB?m2E++SE|ay;Bp(p+|iF}_eZIXp08 z+i)KH6YToLXl{#V4ucCVA*jv7@2 z2Q`-!;f}hl2zS)DCI~&D2}0k~1fd^lg3wPiLFnfT1TVJt=9Q4lJ@tWpSs(|akx +static inline void outb(uint16_t port, uint8_t val) { + asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} +static inline void outw(uint16_t port, uint16_t val) { + asm volatile("outw %0, %1" : : "a"(val), "Nd"(port)); +} +static inline uint16_t inw(uint16_t port) { + uint16_t ret; + asm volatile("inw %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} +static inline void outl(uint16_t port, uint32_t val) { + asm volatile("outl %0, %1" : : "a"(val), "Nd"(port)); +} +static inline uint32_t inl(uint16_t port) { + uint32_t ret; + asm volatile("inl %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} +#endif \ No newline at end of file diff --git a/kernel.bin b/kernel.bin new file mode 100644 index 0000000000000000000000000000000000000000..1c68ac117a1779bf0751063ef94ae792bd3277b7 GIT binary patch literal 1115400 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 literal 0 HcmV?d00001 diff --git a/kernel.c b/kernel.c index 2ebc1fc..6ac6334 100644 --- a/kernel.c +++ b/kernel.c @@ -12,7 +12,7 @@ #include "widget.h" #include "font.h" #include -#include "NIC.h" +#include "nic.h" #include "pmm.h" #include "task.h" #include "syscall.h" @@ -22,6 +22,7 @@ #include "heap.h" #include "console.h" #include "dirty_rect.h" +#include #define VBE_INFO_PTR ((vbe_mode_info_t*)0x8000) void counter_task(){ int i=0; @@ -59,11 +60,12 @@ typedef struct { uint32_t physbase; } __attribute__((packed)) vbe_mode_info_t; -extern vbe_mode_info_t vbe_mode_info; +vbe_mode_info_t vbe_mode_info = {0}; void kernel_main(void) { gdt_install(); idt_install(); + memcpy(&vbe_mode_info, (void*)0x8000, sizeof(vbe_mode_info_t)); pmm_init(128 * 1024 * 1024); heap_init(0x00400000, 16 * 1024 * 1024); // 16 MB heap at 4 MB vga_init(); @@ -73,7 +75,6 @@ void kernel_main(void) { vga_print_string("===============================\n\n"); syscalls_install(); paging_install(); - console_init(); FrameBuffer fb; fb.address=(void*)vbe_mode_info.physbase; fb.width=vbe_mode_info.resolution_x; @@ -85,7 +86,7 @@ void kernel_main(void) { my_font.char_width=8; my_font.char_height=16; my_font.bitmap=NULL; // Assume a function to load a bitmap font - console_init_graphics(&fb,&my_font); + console_init(&fb, &my_font); asm volatile("sti"); keyboard_install(); timer_install(); @@ -111,7 +112,7 @@ void kernel_main(void) { clear_screen(&fb, 0x000000); draw_circle(&fb, xc, yc, 50, 0xFFFFFF); - Window* main_window = create_window(100, 100, 400, 300, (char*[]){"Main Window"}, true); + Window* main_window = create_window(100, 100, 400, 300, "Welcome to SimpleOS!", true); if (!main_window) { vga_print_string("Error: Failed to create main window!\n"); for(;;) { asm volatile("cli; hlt"); } @@ -121,7 +122,7 @@ void kernel_main(void) { vga_print_string("Error: Failed to create label widget!\n"); for(;;) { asm volatile("cli; hlt"); } } - Widget* button = create_button(100, 100, 100, 50, "Click Me", 0x0000FF, 0x00FF00, 0xFF0000, 0x000000, 2, 0xFFFFFF, 0xFFFF00, 0x00FFFF); + Widget* button = create_button(100, 100, 100, 50, "Click Me", 0xFFFFFF, 0x0000FF, 0x000000, 0x000000, 1, 0x000000, 0x000000, 0x000000); if (!button) { vga_print_string("Error: Failed to create button widget!\n"); for(;;) { asm volatile("cli; hlt"); } @@ -141,9 +142,6 @@ void kernel_main(void) { widget_set_font(&my_font); //Scheduler takes over, chillax!! - #define CURSOR_TRAIL_LENGTH 8 - struct { int32_t x, y; } cursor_history[CURSOR_TRAIL_LENGTH] = {0}; - int history_index = 0; uint8_t last_buttons = 0; int32_t last_x = -1, last_y = -1; dirty_rect_add(0, 0, fb.width, fb.height); diff --git a/kernel.elf b/kernel.elf new file mode 100644 index 0000000000000000000000000000000000000000..ee87775430697b4b9c1d26bc14ac600691f9df32 GIT binary patch literal 55593 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≧&tAcJ8`tyD_UTxU2e4(CpeY`k?- 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 literal 0 HcmV?d00001 diff --git a/keyboard.c b/keyboard.c index 7080361..9265815 100644 --- a/keyboard.c +++ b/keyboard.c @@ -3,16 +3,8 @@ #include "vga.h" #include "shell.h" #include - -static inline uint8_t inb(uint16_t port) { - uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outb(uint16_t port, uint8_t val) { - asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); -} +#include "window.h" +#include "io.h" unsigned char kbdus[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', diff --git a/keyboard.o b/keyboard.o new file mode 100644 index 0000000000000000000000000000000000000000..52a617fb043aa0b4218599d18c2baee70ab17197 GIT binary patch literal 2358 zcmb_dT})g>6h0Rg%<{Z|fF;(p$h%DP8MQD3wAfg=&AO-u=7#!)|xCcW3#t zB_s_~wI3Uo2!0zMii};nw3sybsjow=33Cb|0rEshecr z-6Gxc4(e&kENt4|&8!kO#w)q;D>UCRz6ds!df0;TWMt+yle<%y!pv4lxb$`EUJK91 z_SN0RLHnL1i+!orUi%~V!7>8$Ip$$)>!{fJg6G?oG3MQREWJ+R-&Uy3E%(>#&3rzo zhxHp4JN5B68@+a#7m&l$@hfnTBcjQSFJmBDADJ=MV&9X;seAR=n`BV8*ZHh{|LYCS zjZNx-ipp~rPL7H{R4-9tgn}zF_FZR58V(5(H_)E|XGQ~C9 zL39t8ssHxs+S;E#+;QZE&ZDgdU#zISHmT`sIvI+^$6l)fcf#in1joaXW6!zZ%FL8^ z!V|sPq8$4F=I@Utm^%^)MFVnJoA$)qx=;4$p$Sb_6h(%yvjdn0+NqwNF1c|;o9Jwj zPb5PTCVQskGozPA+vT_(8`r$7Np9;<+Lcy-n%t_TnGuk#S4ee_TP%yX6Sc_KW1&6c zM>%Y*NRz zD8+o~o~wZhL`GK40<{X%hiE72%3%Nzo!uH3MP%cgOX$W0Vgk(y^d=&ik9`Y~5$_#D zMm*}Fcs1Y<=!!sbffRozqM=9j=U)H;DSuoPufZDiuAC#`oFzERwp9v9{|N14DYjGq zx_Dj4^dUq0zO6Zro@`=V#F*mH$@v6J@$A*e8g>I48da>>k(a=Gh@6kq7?Q$Q3}v{Z zA7Dd!x^0Co7(HCL>m)T<;p@d$Dm4~s3SKV$MWp?v7rZYY?*9)rG9Z#r{ zm^WMyF`zMT(2Wtr9Fy)4Q~fbr4MpQgBLcq#(dRegzvO6SWPBWTG8Fa2CUfahXv$cN dMDk27^hCgoYY0V|nqb%jKn>~F^7Dwr{tZM3VzdAN literal 0 HcmV?d00001 diff --git a/lib.c b/lib.c new file mode 100644 index 0000000..761accd --- /dev/null +++ b/lib.c @@ -0,0 +1,41 @@ +#include +#include +#include "pmm.h" + +void* memset(void* ptr, int value, size_t num) { + unsigned char* p = (unsigned char*)ptr; + while (num--) *p++ = (unsigned char)value; + return ptr; +} + +void* memcpy(void* dest, const void* src, size_t num) { + unsigned char* d = (unsigned char*)dest; + const unsigned char* s = (const unsigned char*)src; + while (num--) *d++ = *s++; + return dest; +} + +size_t strlen(const char* str) { + size_t len = 0; + while (str[len]) len++; + return len; +} + +// Simple heap implementation for malloc/free +#define HEAP_SIZE 1024 * 1024 // 1MB +static uint8_t heap_memory[HEAP_SIZE]; +static size_t heap_offset = 0; + +void* malloc(size_t size) { + if (heap_offset + size > HEAP_SIZE) return NULL; + void* ptr = &heap_memory[heap_offset]; + heap_offset += size; + return ptr; +} + +void free(void* ptr) { + (void)ptr; // No-op for simple bump allocator +} + +// Stub for syscalls +void syscalls_install(void) {} \ No newline at end of file diff --git a/lib.o b/lib.o new file mode 100644 index 0000000000000000000000000000000000000000..cd0a0a1fefb98b4bc42225b8e75da4b46df0d6cf GIT binary patch literal 1436 zcmZ`(O-vI(6n@igNu#AL0#VV!8XF@>mLDOp!~-oQdVqxR<8P#tx+|ErH0>0nnusYs zZJH(=HSwScM-LthCl8x8!of=qCSJT5p9xqpj;4BX{ya-cj zM^7c)j$ym0lEZxc9bLT@?n@NpiOa1sfr_@roL?}j;IPb;rPxLb;pmP$kAX*<(=+4ZJ&3n;SpDQeRl2F{QHf)qQu7H?K*#x96zAv^AxgG&1q?c6QJ@>AzFJ&-V|d zd2G(-YRZngY+3GdE~~te6*Hd{WBt1OcVahFob(rR81x1p1M)#S0;R?Nz#-Rjx03)*dp z;?zg@bYB_A5L5qk&}^U<1Bp08tD0cMK-@rS z1HCZN8v{woY)Hn4Y;Pan9t+J*OF^9|jsCD4j?0vhx)i~LmH!#-8vtp7(FJ&k_^^iV zKWgGU7Lp@Stf{f;ns6W#n#1~7<8U6ErlH|v3DFOX9Dpvkh^{k!B_`AV)mbx-9cOgA zh@bwN8hyU}O=uHQ5T3V5(`su|FagCL-l3Eh!}iA(R8WE`^kP9;QPjg`lijwlXHzzMWC_7=f!AfYy~ZnSP}bMdSm5AKFLkt+XT!PT+_6mfp_ ztC*|ovo*_gpl*nM2)+x`C#;|IX*tVIhrjx7K_{MrkMLckp^1Y;7Zv#GR+7RlcRz#Lm#%I8d#I`fMC zws0RY3uSaAAmIQa+AF%oqyRTisSB5xMC&ao6lock);//Initializing the guard mutex->locked = false; diff --git a/mutex.o b/mutex.o new file mode 100644 index 0000000000000000000000000000000000000000..2ee107b4fdffb5b16839c765b6f7db6ada2d5df5 GIT binary patch literal 1465 zcmZ`(&rcIU6rOEYQ+2a6ii(lL9x6)22zN`8KLiWMk54rdR7=_$_qRtu2a6?Dx5z<#xXD#bUf;X`Nyx!}LtR8@p zx28V>^+tO82YtxxHs~SX-GFaEL4&+x@pni0QA{ay#(rVErisMSBIr7rgr>OLF|$)q zw?1?sdN2(c(O^cY#uH1^n#O9v;r?j3p_>``c3K7_n5Uf?)jm|vQceXxaUh{s+g^0JMVaJY@HEFZT zhSP1iu>`0p7E8CyeonW2*CNiy7+f1^QM~@Wf%7={QK?i$HSMNyWs&is(VRArOF_)jx6zf*{2h{Aa-Vl`|$|W#(X3d=A9)pm6@Tx62 zE+yE{xJ+2M1_rzMP=dXTEf;RskIM`8G4@z14l?h!bp8gy!c`A7nsE=}-zO|=qi!Ss znyN?Oe7Jvjf_~&h6X$JHGv>x$*`d7{z{z3e(PQmb~xq> 16) == RTL8139_DEVICE_ID) { + uint32_t bar0 = pci_read_config(bus, device, 0, 0x10); + rtl8139_io_base = bar0 & 0xFFFC; + found = 1; + break; + } + } + if (found) break; + } + + if (!found) { + vga_print_string("[NOT FOUND]\n"); + return; + } + vga_print_string("[OK]\n"); + outb(rtl8139_io_base + REG_CONFIG_1, 0x00); + outb(rtl8139_io_base + REG_COMMAND, 0x10); + while((inb(rtl8139_io_base + REG_COMMAND) & 0x10) != 0) { /* wait */ } + rx_buffer = (uint8_t*)pmm_alloc_pages(4); + outl(rtl8139_io_base + REG_RX_BUF, (uint32_t)rx_buffer); + outw(rtl8139_io_base + REG_IMR, 0x0005); + outl(rtl8139_io_base + REG_RCR, 0x0F); + outb(rtl8139_io_base + REG_COMMAND, 0x0C); + irq_install_handler(11, rtl8139_handler); +} \ No newline at end of file diff --git a/nic.h b/nic.h new file mode 100644 index 0000000..ab48e25 --- /dev/null +++ b/nic.h @@ -0,0 +1,6 @@ +#ifndef RTL8139_H +#define RTL8139_H + +void rtl8139_init(void); + +#endif \ No newline at end of file diff --git a/nic.o b/nic.o new file mode 100644 index 0000000000000000000000000000000000000000..1ac9c28105c2fad7871ce290a23f8b579ff5d9f7 GIT binary patch literal 1696 zcmah}&rcIk5PsV(q!z5iRMd#cORNU5t}Q|YMFO@_8u?KQ8nwW>w7X@sw6)zfSUpIZ z7zj4uAMnHlFCL7EJ!nD#fxp0L;=wCMgp2WlL1%W$c1tl%^4|Mq=9}4hv+uoLrkbF1 zvVYTua<|DrNLpj7kwdLte5x zVGsBeQ#l#(bzNvFw>d$5zaP)tT1HHOwhp`|*eeQ#V7}ajbB%SNWgVwO@2ZfH_jgJ^ z7Mb(`X)CwlT+U|*kgVXC^*S2%5a+=3{S%jedj=EScK;g6ZP*n?xs#(Z`E z$Olo_gwwzO5VC;VQsd_iB6Kh12Lqc049yQ-+MM6bx3O54-iE+E^abDn(X~~mQbC8b zRXC&~?^Xdfgh^me7>2#7fyGemye`3hpNIMagQJA{h0sG$p#d=@${8_Ci7zHAvJjQC zax6jv!@X_pi|ri8Q4$=uIcg=r{()h7ec)EV7nBUWT1Ag634#SKG zsG6LES@Ysi*1Y(0HSay$%j@15KzQ%$Q(zG zKpL-6M}9!KgK9DY=%~u0s*V+O=!lc#s0bR$4xF$E6O%(+NHZAb<3-F6N=%TkBWf0F>;(A7gCsHiXTr)5{73Y0-s3A wF@;YlutW%-2+4d>6vBKc9+PA=OiuDbG#U@_2_Yh;2rnle@p3GsfKjjGFAg~a#Q*>R literal 0 HcmV?d00001 diff --git a/os-image.bin b/os-image.bin new file mode 100644 index 0000000000000000000000000000000000000000..fcd1f3ef35598f089f1fb5340dba7bb8259c2dd8 GIT binary patch literal 1115912 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 #include "paging.h" #include "vga.h" @@ -21,33 +20,19 @@ void paging_install(void) { // Initialize page directory - clear all entries first for (int i = 0; i < 1024; i++) { - page_directory[i].present = 0; - page_directory[i].rw = 0; - page_directory[i].user_supervisor = 0; - page_directory[i].pwt = 0; - page_directory[i].pcd = 0; - page_directory[i].accessed = 0; - page_directory[i].reserved = 0; - page_directory[i].frame = 0; + page_directory[i] = 0; } // Set up first page table for identity mapping (first 4MB) for (int i = 0; i < 1024; i++) { - fpage_table[i].present = 1; - fpage_table[i].rw = 1; // Read-write - fpage_table[i].user_supervisor = 0; // Kernel mode - fpage_table[i].pwt = 0; // Write-back caching - fpage_table[i].pcd = 0; // Cacheable - fpage_table[i].accessed = 0; - fpage_table[i].reserved = 0; - fpage_table[i].frame = i; // Identity map: virtual = physical + // Present, Read/Write, Kernel-mode, Frame address + fpage_table[i] = (i * 0x1000) | 3; // 0x1000 = 4KB, 3 = Present + Read/Write } // Install first page table into page directory - page_directory[0].frame = (uint32_t)fpage_table >> 12; - page_directory[0].present = 1; - page_directory[0].rw = 1; - page_directory[0].user_supervisor = 0; // Kernel mode only + // Set the first entry of the page directory to point to the first_page_table + // Flags: Present (1), Read/Write (1), Kernel-mode (0) + page_directory[0] = ((uint32_t)fpage_table) | 3; // Load page directory into CR3 asm volatile("mov %0, %%cr3" :: "r"(&page_directory) : "memory"); diff --git a/paging.o b/paging.o new file mode 100644 index 0000000000000000000000000000000000000000..7e7ccbd11dab7f6733a77bf51d8137d3e6557b32 GIT binary patch literal 1181 zcmZ`&&1(}u6n~RVOOV7(Gzg-|P>NVA)3jJ9in2Bb5kF}Wlp@|CtzxmC3^WK}8ca;qS$(IPg zVTqzlxaI>_VqbYUMH#?tv>}P(;4nWg77f>s%>GJ)j3;uHN{CVa`;JV z6_Nm!y6IUfY6@B&S5sQ&JaB;Orlr=tzKTjCRDaY`0%4c@0H=tbu(SCUn zdE6+yZh1*d-TsLCow%j`TJulC5Y=z1WYc=DJf(;-tUB~rq=Bl4N$zxj&IKro$oHrRTr)t+0cr>62_oO)86rOhM?^WLL0ERd zL`1Uv7a-5Nm$Tq=JNjrBFnrqxUDGZJcLQxJjOwKx_%Gp3khi?oIiW6~S5PS6E(v!4 zRiQ9^f<0uU%MIYHFuKit*=Z8$Z-vp{?@#Iix#6#)d?;^#>r#iAxh_LJAAu!Y`B@G( z8VwNUJ>7DQB@=Z2c6HnTjQbmz`l9XNA1gU^&@J>bb=Sz@Q|Yz5p_d)I=;{?0r#$=v DkTa`X literal 0 HcmV?d00001 diff --git a/pci.c b/pci.c index d81aa08..489a518 100644 --- a/pci.c +++ b/pci.c @@ -1,10 +1,11 @@ #include "pci.h" #include "idt.h" #include "vga.h" +#include "io.h" #define PCI_CONFIG_ADDRESS 0xCF8 #define PCI_CONFIG_DATA 0xCFC -uint32_t pci_read_config(uint8_t bus, uint8_t device, uint8_t func, uint8_t offset) { +uint32_t pci_read_config(uint16_t bus, uint8_t device, uint8_t func, uint8_t offset) { uint32_t address; uint32_t lbus = (uint32_t)bus; uint32_t ldevice = (uint32_t)device; diff --git a/pci.h b/pci.h index 23d79d5..4602263 100644 --- a/pci.h +++ b/pci.h @@ -1,6 +1,7 @@ //This is for the connection header -#idndef PCI_H +#ifndef PCI_H #define PCI_H #include void pci_scan(void); +uint32_t pci_read_config(uint16_t bus, uint8_t slot, uint8_t func, uint8_t offset); #endif \ No newline at end of file diff --git a/pci.o b/pci.o new file mode 100644 index 0000000000000000000000000000000000000000..883e7206fa9acf6fe564883762fb63047dbd2f1d GIT binary patch literal 1314 zcmZ`(O=uHQ5S~r8C9QE2G#I zVh8XT8P7?&GN&7PbKwAZ^c@?kdod7*Jd%=eJ#N)?$OF*-UYg41J5X)VJk{me8wOCp zH=o%OW52-FYpse!FNSa@oo}#Bn8qrLIzRqaYIF zh|b!sgJq7|?unl5jeRG;Nu=k0Y#dChHAoMpV6Y~7mbLx4{;-3M6$N$uJR`3Z&Bqs zH~`9j05~YTEN{|SK17ytE$H}&$_MY{L-|2{*<#T|T+>u7MIxawGF8Y+lGF>MnSz!y zkfc&n6AHOPVv3f`J5F1Ul6f-|@!ID#Jq{tn9Vqd+&ra6N_Yfn^hWWnwFsoi^Cl zCi})@-N17--F*}#WmA+ZKjhQ8$kC9KdAv0L9{|m8HDuJY=<>_4fu>vxlx13YrNjZ_x frqvV!@_5Dnqc5i7ayF-Gx}4WB;D#e4t<1q+V4%;K literal 0 HcmV?d00001 diff --git a/pmm.c b/pmm.c index 4596312..108e966 100644 --- a/pmm.c +++ b/pmm.c @@ -40,7 +40,6 @@ void pmm_init(uint32_t memory_end_bytes) { } page_frame_database = (page_frame_t*)(uintptr_t)KERNEL_RESERVED_END; uint32_t usable_start = reserved_pages; - uint32_t usable_pages = total_pages - reserved_pages; for (uint32_t i = 0; i < total_pages; ++i) { page_frame_database[i].state = PAGE_STATE_FREE; page_frame_database[i].order = 0; @@ -104,6 +103,38 @@ void* pmm_alloc_page(void) { return NULL; } +void* pmm_alloc_pages(uint32_t count) { + int order = 0; + while ((1u << order) < count) { + order++; + } + if (order > MAX_ORDER) return NULL; + + for (int i = order; i <= MAX_ORDER; ++i) { + if (!free_lists[i]) continue; + page_frame_t* block = free_lists[i]; + free_lists[i] = block->next; + if (free_lists[i]) free_lists[i]->prev = NULL; + + while (i > order) { + i--; + uint32_t base_idx = (uint32_t)(block - page_frame_database); + uint32_t buddy_idx = base_idx + (1u << i); + page_frame_t* buddy = &page_frame_database[buddy_idx]; + buddy->order = (uint8_t)i; + buddy->state = PAGE_STATE_FREE; + buddy->next = free_lists[i]; + if (free_lists[i]) free_lists[i]->prev = buddy; + buddy->prev = NULL; + free_lists[i] = buddy; + } + block->order = (uint8_t)order; + block->state = PAGE_STATE_USED; + return addr_from_idx((uint32_t)(block - page_frame_database)); + } + return NULL; +} + void pmm_free_page(void* p) { if (!p) return; uintptr_t addr = (uintptr_t)p; diff --git a/pmm.h b/pmm.h index ec7e5d9..72a96ef 100644 --- a/pmm.h +++ b/pmm.h @@ -17,6 +17,7 @@ typedef struct page_frame { } page_frame_t; void pmm_init(uint32_t memory_end); void* pmm_alloc_page(void); +void* pmm_alloc_pages(uint32_t count); void pmm_free_page(void* p); uint32_t pmm_get_free_memory(void); #endif \ No newline at end of file diff --git a/pmm.o b/pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..0bfd2c9e860694aa9da3e604d1ed8ab1bc891951 GIT binary patch literal 2855 zcmai0e{2&~9Dmo|+_}}e3XK^$lQUijgi`1nhAPH(Wq<_8V2CmN=*sMH*tywWi7Xmj zZa4OFX(TZkH2#Q*!5CtUiQ<%hS_?gwB~pHg0nrJG4obs9kZfqE-*@kN?S93V+-HV^`6>r0b*h*bFn2R+HJ z7ZUsQR`)xISxGsw{t2Y}$4O83-y)6g$HZt-LpB?Y0+T9N7A%?I0g|}E7S2qN?q^{D;ctmqy)E1E8Wyt#TO$!z$>)}0eadle`>xQ=jHL%=!9QVO zbjFn%kI{nMjYa%rArMO3LsewE%LO*^)%6N*zvQG`Ey(;*j3tAQ{rh_Cbdx z;+k@tO+|JeH}Qxv zStGpl8IbS=&HauDKrIOUhoRM)5oW2SB1J2V6pbw&$2#Q3cjom?n3eD;EB_VxY2K;+ z@e2J;^)%>jnx@}30{U4gJ<1L4nY`9wN$63g#H`|`^?5}i?5+`V7i*!p~HgV+=6 z-WzF`7mMB%o(9iygj^tv6sC6zVqW8zha4+c&&xwdox+ zy|)7W5PZks@>S10cb#nnrVdV8r7D;Pr zkq9o!VLfLdDec6+h35uHP87SXIRnbGJUb7}^WnP(HCX7ph3w!>M|lgqVxf;Mbk0Hr z3*EKQM#u||lCaQS3pqg@9eu5@?xkX7Ve6m5bR{A^W{z%h2(BI91Zn^_eA1ghK5o? y#A|mr4&07dBoc~t#$`ePzi>3#-EL5)_f3M~Ktj>+JrSA4=!$f8$M(;@qW=KzcWB`N literal 0 HcmV?d00001 diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..f0fd433 --- /dev/null +++ b/run.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Define the ISO file +ISO="simpleos.iso" +FLOPPY="floppy.img" + +# Check if any image file exists before trying to run anything +if [ ! -f "$ISO" ] && [ ! -f "$FLOPPY" ]; then + echo "Error: Neither $ISO nor $FLOPPY found." + echo "Please run the build commands or build_iso.sh first." + exit 1 +fi + +# Try to find QEMU in PATH or common Windows locations +if command -v qemu-system-i386 &> /dev/null; then + QEMU="qemu-system-i386" +elif [ -f "/c/Program Files/qemu/qemu-system-i386.exe" ]; then + QEMU="/c/Program Files/qemu/qemu-system-i386.exe" +elif [ -f "/c/Program Files (x86)/qemu/qemu-system-i386.exe" ]; then + QEMU="/c/Program Files (x86)/qemu/qemu-system-i386.exe" +elif [ -f "/c/Program Files/qemu/qemu-system-x86_64.exe" ]; then + # 64-bit QEMU can also run 32-bit OSes + QEMU="/c/Program Files/qemu/qemu-system-x86_64.exe" +else + echo "QEMU not found. You can bypass QEMU by using the generated files:" + [ -f "$ISO" ] && echo " - $ISO (Use with VirtualBox/VMware or burn to CD/USB)" + [ -f "$FLOPPY" ] && echo " - $FLOPPY (Use with VirtualBox Floppy Controller)" + exit 0 +fi + +# Check for ISO or Floppy +if [ -f "$ISO" ]; then + echo "Booting from CD-ROM ($ISO)..." + "$QEMU" -cdrom "$ISO" +elif [ -f "$FLOPPY" ]; then + echo "ISO not found (mkisofs might be missing). Booting from Floppy ($FLOPPY)..." + "$QEMU" -drive format=raw,file="$FLOPPY",index=0,if=floppy +fi \ No newline at end of file diff --git a/shell.c b/shell.c index 5984970..710a1e1 100644 --- a/shell.c +++ b/shell.c @@ -3,6 +3,7 @@ #include "vga.h" #include #include "timer.h" +#include "io.h" #define MAX_COMMAND_LENGTH 256 @@ -48,16 +49,6 @@ static void shell_halt(void) { } } -static inline uint8_t inb(uint16_t port) { - uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outb(uint16_t port, uint8_t val) { - asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); -} - static int shell_strcmp(const char *str1, const char *str2) { while (*str1 && (*str1 == *str2)) { str1++; diff --git a/shell.h b/shell.h index dbce648..40e7999 100644 --- a/shell.h +++ b/shell.h @@ -8,14 +8,4 @@ void shell_init(void); void shell_handle_input(char ch); void shell_print_prompt(void); -static inline uint8_t inb(uint16_t port) { - uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void outb(uint16_t port, uint8_t val) { - asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); -} - #endif \ No newline at end of file diff --git a/shell.o b/shell.o new file mode 100644 index 0000000000000000000000000000000000000000..c9fbb944ec81fe42cdf104466615acf31d514e84 GIT binary patch literal 4340 zcmb_fZEPIH8J=|xr_wL4bNA7N| z-92NcDJ1xSoWRrq{(uC6e|$(Nd?>gPf=g{B{ZX~5N~Kg$TcjeC!}K2#QfRn7@6OHZ zbq=IPVx*mY=9%aHn3)R>G2NGw(tO(Cjb^3@zEl#$h`W?Z-8KJINvl!uX6qFUOZ*Qa^@?xD$>saoZ8iSh#!zYFu%l_%NG@Lwj$uZ5%Bky~;w^n*Zxia`k8bKK1bxl}_HWf8_Mv z|8KoM&iTXNkE8z3cB5@%eGBIp>mH2YYy=;R;NubeXM=0MLfF|!acTZN=V}i|MVZjmEd z_kI~SK?FXtLbH#DjD>y;U4Q0^j ztSHuSn4fkOswoU*3oq#2Lnw@*JLAF(7Fnu%J}$PeDDk+6vtqKx-b{J*%cSGyQgW*I zR_RVC51AA*vXR_DSw$AW!lS4DsPj#Q%xsb$4g^C z6Qv+7bneT(Y}*d~jObz0C{)^(2i%e@IMcF7vs&_s(j6a{({9P51%M;v!EApnbr6BY zh)TIw5)9*~#e=XYnpHwyeE;->k~h;r-7GPs(rH>s8xtVn1A1X);JPyJ7Be@3O06*ECrVrhj;WgX8+A-s?HKUaBVqhKP<{M|r<`9DL7-2(%Ca>KBi?A;`9E9J0i z$!R$>a$sbOobcTHR4VwM?AdB>u{R6RNt2CY9U2za;Wq2qZ^mNBu=|LoPYInw?#3ks zI%LaGM{Fk`9eL8Y-lWd{j<%T=>U=rg(bm7v5xb*(UjyxKU$v&Cfp@k04RlvK`JTen zjg35qd+7V|j@UJT^!e))*Q5SUh;BknpVU_Iebikcw*$4--43L6j{xD=2;DQNwZ-#5 z+Ts)cDPG2QzPkhXmvNPGSlkoNo$koLC(q%G(up>=C8SK780=)2%M#dhX~ z899tHK-yoPIiJxf?mf+%g;$rhXa&;I`kC9s+)?HpVeUQV7MZhf*lhR%(j&SGNPE7T zxizf2p1Cco+remPfb?qFKsvvztm|W4KXbd78)9ylxdY7I%bW+KpYh)S z>Ag^9U4?bevF;_-CGhNOi#xG``Z;)*k;Ht``>a#+GCIu29?#_!T2#KkM$1?}eO>I7 zrnshOg^DGlXhFQ?f~jj1Iy#NvYSy$h6nKF(5YiKL39%2C#I?+f5rfe+`#}dv^e>fC zS!ErEIvw_zD*A_ttq6_jS-waAPQ&PyY*I!4OlhR6Ec$b3F8Kz9M4;K&EC6$VgKZ5p z^iQg1ph1VXqujtehxo}R=7lDPPV>4Lt5b#$hWS$y^Y<0ZhiK{1b{{%)NZ2YnI_^0* zH;sl*#OQ>VD+Z|XntPQnk6OGfu=CaqG9W+|YryBN)=U^Jkkh356i@PFI~HD&++ literal 0 HcmV?d00001 diff --git a/spinlock.o b/spinlock.o new file mode 100644 index 0000000000000000000000000000000000000000..587cbbd5aacb675d5b60e384d22b3bf746b7ef0f GIT binary patch literal 914 zcmZuw&o2W(6n@iP(u9Zz2jQ@Xrm2weI}vdZBpgT@?Zw4fHCU=;cLM(m z39!QaO*fa#XV!T}scLKu6NddFbRs{XJt-t`q8locked = false; + lock->locked = 0; } /** * @brief Acquires the spinlock, spinning until it is free. * This uses an atomic test-and-set operation. * @param lock Pointer to the spinlock. - */ + */ static inline void spinlock_acquire(spinlock_t* lock) { while (__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE)); } diff --git a/syscall.o b/syscall.o new file mode 100644 index 0000000000000000000000000000000000000000..4b3431067d9749b5fdd9b8604fce93903cf4719d GIT binary patch literal 1028 zcmZ`&?`qRf6hC*#MCKSn`$ep9g);n8uG?@>H-u^uM=`af5k(PV+TM1NtSiZNxZ($4 z2*Mcj5qt+`&I8h$RYq`Out>k zTieJHP0W5GuabTTIqG-#r+B89i294n;g8~}I94klj=!%EaAcPBqbmP$qUKKtKf`<# z@!wP&kH^kI)bWCV*9J<4J+C7%iWDNUTjq|xI}9XmIQ&(k^{n=MdjXu+&I_x~jmNgl zTb5zfURvfYWY+3U+sZKkwhd#G-)_nMN|`_T;0KDg4|p9rtn*>G_g;3?9lo|9)&(A@ zK<7bWqZY7Fm)VU)UH^*TOL!5L-YtG(V~IDGbXdlmu980eCMpR{!(!~OpuLJ(h&c)N zaDs7+h+BZlBoaM8keHGD{RhxzQF1e)lYptco_Yox=5p^wCrsonI*vNcN$S}dr4|}{ zg!X(rv9j|?Z>{C_A_j6Yv#DWzAty7Jw1dXp(9$W{N|AZ=8oM`DC*Wy{(%osyM4Jv{ zij!+jV!R({W0w3GrO{{vLhiV|(A$;Zrnl?*$+VpVJKmrh$Z*E8{l4c8Lw}&$NTKV) Ee_Tt22><{9 literal 0 HcmV?d00001 diff --git a/task.c b/task.c index a5d3bcc..9f6fd18 100644 --- a/task.c +++ b/task.c @@ -38,7 +38,7 @@ void create_task(char* name, void (*entry_point)(void)) { // Since the x86 stack grows downward, set the initial stack pointer // to the *top* of the page by adding PAGE_SIZE. // Use explicit cast to avoid pointer arithmetic surprises. - new_task->kernel_stack = (uint32_t)pmm_alloc_page() + PAGE_SIZE; + new_task->kernel_stack = (void*)((uint32_t)pmm_alloc_page() + PAGE_SIZE); uint32_t stack_top = (uint32_t)new_task->kernel_stack; registers_t* initial_regs = (registers_t*)(stack_top - sizeof(registers_t)); memset(initial_regs, 0, sizeof(registers_t)); @@ -103,4 +103,9 @@ void schedule(registers_t* r) { // Restore the state of the new current task *r = current_task->regs; +} + +void schedule_and_release_lock(spinlock_t* lock, unsigned long flags) { + spinlock_release_irqrestore(lock, flags); + schedule_from_yield(); } \ No newline at end of file diff --git a/task.h b/task.h index 560f46e..a7e03af 100644 --- a/task.h +++ b/task.h @@ -2,7 +2,6 @@ #define TASK_H #include #include "idt.h" -#include "sync.h" #include "spinlock.h" typedef enum { TASK_RUNNING, @@ -25,5 +24,6 @@ void tasking_install(void); void create_task(char* name, void (*entry_point)(void)); void schedule(registers_t* r); void schedule_and_release_lock(spinlock_t* lock, unsigned long flags); +task_t* get_current_task(void); #endif \ No newline at end of file diff --git a/task.o b/task.o new file mode 100644 index 0000000000000000000000000000000000000000..27c9f7058e891d1ac4b13c9b99e8c18aa4d249f0 GIT binary patch literal 2220 zcmZ`)-)kI29G|^xjx)b5p%;rZ)m4@fF|27xp%sP8ZCX!z#gN!SsmW%0x4Ev}`_a3- zkQ_b~&PbQ@;2wPNMWpn_Cs8a2q7b~;dyuN=AK;4>B?X1PNEP+-o!Q&md39js`r1@9be2sXeUO^RO)BSq!XXknaX3$MNjCb^S4{;a0P4J#VtW+p+>@R+U zHr`rqYK>b*$X~lR)s|^-_Dj&T7u3iida%T1o~+&^z!~*Pay1gtO|o3h8*j&x)N98V zgh_EDtB=ES9-ms6yHkRijH@N8OB(lT2 zaAQ&O_*VE>V<56MD>BjcxC^ll8@vcRuA6Q-3zBKQ6AWv?vabAG^1a+WVEqb*?^1+TPvz z*~s?yu5&+Hkm`wKbRr=G&W{7c2q*w5fmwh#$e;GU+Y7HZPk!m9>hV-V>~YV zXUj7Xosh^Ei%!gs6HoyZ0&@VfE68g*!Ov&!<4%67Ny+^gUJ7lc)kMDQ3##fNwXjO( zZ0{(PoMy90hx=0Ac5TzKt9CxCoj{*HGU<{Th|ck43gaiP6F2TLU#Y^x;rz{`UM= zSnSj=Q!#uUHG_5E54g$E!H_#d6n%J=3}5#njLXRVVd7!^3u7{)bD`@NW{;w!S0T&} zp(Rd?DQM}g$Jhz9g7*T@6WphxJ%Ac!X9BbcBzSosp+^sg@NEJK<@bPu@~1#T?{grb z_f3F)2zUzMFdL+#fY_PLC005u=V84Wl!pf&8iUkC4yUm9ewnSPESbpLzkAO@tvVAEaLFWvtg z9+yPt(p$R!IXqG+(n~ra+%E!% zEOY#AkH^Saxw7T@z7FTd9?oCriG8cpYL#i$Wn;Z$<}7ApE!Rj_N+m1r8g$Fpe|r9V zW!U+$YdQ`y^7zXeMLWZcl4WMLjH?x^0-bXDvX!Yg7IX_aW6QQ2Fw&s7map4kbaBmm z1}ctamMz06q_6zX9yhY4Q7qZmVcCVrGNYKw8Q4uBZ4}KctzNYABoL_CrK=^Y>=sHE F`xj`STaf?& literal 0 HcmV?d00001 diff --git a/timer.c b/timer.c index ef36c2b..a6a7d0e 100644 --- a/timer.c +++ b/timer.c @@ -1,5 +1,6 @@ #include "timer.h" #include "task.h" +#include "io.h" volatile uint32_t ticks = 0; void timer_handler(registers_t *r) { ticks++; diff --git a/timer.o b/timer.o new file mode 100644 index 0000000000000000000000000000000000000000..37068716eb8cc8e834139c96ebaa72136e3cb34f GIT binary patch literal 1034 zcmZ`&OKTHR6h5~zmI@_^#)USED+H-nZeLcUxCl)_7cEG;P*;;_a??zmwmP{j8e9n3 zxGA`ICH@7GECUt#CtMc=e}Wj#cjsm@q4dD{&Uc>oF?Tk^6@uKJAi8OpFO<=5jpZrS z*!*Pei`1WFBk5U9H9`}np-Zts3w^cIZs!a9yyN%>uA6@_o|t3zv0HPP;dzz$#g(CJ z?F+^h*Zp<19{Z^Kf^4@hzQXP7e2U-Q1IlD{4tC z5EaqHB05_n-cN~{Y2W|I`@P1o5-S$C&I&<{TL`P+t|91OXT=pEN7aIi3qIk<)2x$p zHDh-&w!v)5W^qTDQKSOn4a+1WvPC;JWlyu1YDTeU5Att7v@1-suM<^ILmA$3Opv4r zY$p?(DV13^lJ#QE@O(teoX5#7)^Ly||0=PJCu)qNes(DTBKbjc4Wi?ce~ox4o*3;j zU%BQSWIb^|pUU{AWB7+Wfjh>;kpw2HzjALM8SIJZxkUiqnC0PEz1VnzZdgl}jaRNGf%-*D#>=W;daOjRx_(j3(s7DgAchR+y#TQy z*@3~odLiu>ZP{OVyIg(-p|4eF+ClA%04O^pGj)q3wl2VZa0FkTZNlS@VEm z0AsaZ#;>V8eV|>}_ojoyzd?IKdM0ikKx5gfHu<7QO{2i8o>+jRdJyeJdW?BQaZ|g2 zvD)+TKh*9%(9z6&n^UC)Bn5sR$BjA74$R#`dV^>a(v2do@(DNu!m;{AXT?P>6H$5y zoSb9!2kH+x2>4~3r=34K+n7%rg-^gA3z*pkZh}j<%`TnMqw6OSuNK|J{l$2+C~oV1 z8+uKtM$wj@cG8y+Zl|20{yv{nf^0DlSKqZj9z#tcjfA-lOB)fMnmC zGwc-$CZFLHYFEBLC;n633jS}_syiFD=k)x)ys0TAVG3u-gIsbX?i+pGOY=MrjSJ~I z_<}bIxWav(y@qbw*ORI?6g`+}7?75yrqW>U+vA^^oXK(umCN_$#J|pWjui^pj-p3! z_}R_df)nzyQTeS&z9FWz+J<s$ZP;r_e@w6a>?W+9*~C z)BNI$(Rnl;BR>;I<%*o=vZK6wRe(0CoY5WNpvu>U(|*yO%t-UqEusVSVeC_QQOVPP!l2~@QAS8z{hg!cIc8szAi{as6g8@O%*&Z-xlo~e*X^In@4cc{xkl?It4ps@7cc;&xunptMU;N*6ZxNj zG^_TOR43o$g!DSX+AKa`s*Jf!M)E&Cfb7yc0K262Ry-%4bwgRU>UA0Ni?j^7^!oCD z3x%HlLDe;jpINf>+2@wk`c^dfSFT#!(D1zH$@SsRWmTRP@s_CM*|FcVuIbgL#h&(9 z+iT&Fw9r$t)VtUVy-*1rB5_^o33tH8J>ul~Zn)?0?wkvZ9Xu5n31!$mxMv+O63YC* zJAoU4kx=#u@CjhNBau)R1wIS>1TYfH62N}}9|A`503QQRf)D#)BtDl-wpdo#b1wcR z$2Ry9g76U7}^!?yB_VTyC)M1p7AMITyd$ zv9?r5$aJuYH&HoxjG?C)3Ndt&As=|4?KsNNTMQj%=p;j@7#d;dXNK-D^f1J(`@+zR z3~gX2$WWA_LkwL4^eA{+PCkY_Y4!#f`ih}j4Bca>97>_>n8lC>Y|R0#Buf}t!_XFn z+8IhR^fp7EGjxL?H$<*k_C{KwVUQz@6$shIb?$2RhBSfci`qyW@em8_E)w>TMo+G4>P2qWG&3L1D9HMfK;PRFnk1Ds$={@wclZ8 zQXK)L8c8tR0WP&OP1n$VmkG#1sm=_hqauQiDAl3w6{`0ReETNVd5Es#=R@ECq@vW0 zrec0iVqvVDU+*Ao9lz$cBpe4i#We$&-;p%)oYPohqxlU2>U^=RCN+QJA7+IeDER~PYycLyV}<~?CT+bG;B#r6k7ZPB)vCTMAGku(It z_?}jV4TVrN+^p+%geB9?_P9i?HS7C3Lb0}JRND`0q20!|_E<}+6zq^-*rhL1$?otz M^K@r8G`Zvd0Z#m3od5s; literal 0 HcmV?d00001 diff --git a/widget.c b/widget.c index 6c1cfa3..08dc7ab 100644 --- a/widget.c +++ b/widget.c @@ -8,7 +8,7 @@ #include "memory.h" #include "shell.h" #include "pci.h" -static Font* g_widget_font=NULL; +Font* g_widget_font=NULL; void widget_set_font(Font* font){ g_widget_font=font; } @@ -16,10 +16,10 @@ void draw_label(Widget* self,FrameBuffer* fb){ if(!g_widget_font)return; LabelData* data=(LabelData*)self->data; if(!data||!data->text)return; - draw_string(fb,self->x,self->y,data->text,data->color,g_widget_font); + draw_string(fb, g_widget_font, data->text, self->x, self->y, data->color); } void update_label(Widget* self,FrameBuffer* fb){ - // Labels are static, no update needed + (void)self; (void)fb; } void draw_button(Widget* self,FrameBuffer* fb){ if(!g_widget_font)return; @@ -42,7 +42,7 @@ void draw_button(Widget* self,FrameBuffer* fb){ color=data->base_color; } } - fb_set_pixel(fb,self->x+x,self->y+y,color); + put_pixel(fb,self->x+x,self->y+y,color); } } // Draw button border @@ -51,7 +51,7 @@ void draw_button(Widget* self,FrameBuffer* fb){ for(int x=i;xwidth-i;x++){ uint32_t color=data->border_color; if(x==i||x==self->width-i-1||y==i||y==self->height-i-1){ - fb_set_pixel(fb,self->x+x,self->y+y,color); + put_pixel(fb,self->x+x,self->y+y,color); } } } @@ -61,29 +61,26 @@ void draw_button(Widget* self,FrameBuffer* fb){ int text_height=g_widget_font->char_height; int text_x=self->x+self->width/2-text_width/2; int text_y=self->y+self->height/2-text_height/2; - draw_string(fb,text_x,text_y,data->text,data->text_color,g_widget_font); + draw_string(fb, g_widget_font, data->text, text_x, text_y, data->text_color); } void update_button(Widget* self,FrameBuffer* fb){ - // Buttons are static, no update needed + (void)self; (void)fb; } void draw_textbox(Widget* self,FrameBuffer* fb){ + (void)self; (void)fb; if(!g_widget_font)return; - // Placeholder for textbox drawing - // ... } void update_textbox(Widget* self,FrameBuffer* fb){ - // Placeholder for textbox update - // ... + (void)self; (void)fb; } void draw_scrollbar(Widget* self,FrameBuffer* fb){ - // Placeholder for scrollbar drawing - // ... + (void)self; (void)fb; } void update_scrollbar(Widget* self,FrameBuffer* fb){ - // Placeholder for scrollbar update - // ... + (void)self; (void)fb; } void handle_button_click(Widget* self,int mouse_x,int mouse_y,int button){ + (void)mouse_x; (void)mouse_y; ButtonData* data=(ButtonData*)self->data; if(!data)return; // Change button color on click @@ -93,14 +90,16 @@ void handle_button_click(Widget* self,int mouse_x,int mouse_y,int button){ } } void handle_button_release(Widget* self,int mouse_x,int mouse_y,int button){ + (void)mouse_x; (void)mouse_y; ButtonData* data=(ButtonData*)self->data; if(!data)return; if(button==1){ // Left click data->bg_color=data->base_color; - data->border_color=data->border_color; + data->border_color=data->base_color; } } void handle_button_hover(Widget* self,int mouse_x,int mouse_y){ + (void)mouse_x; (void)mouse_y; ButtonData* data=(ButtonData*)self->data; if(!data)return; // Change button color on hover @@ -108,12 +107,20 @@ void handle_button_hover(Widget* self,int mouse_x,int mouse_y){ data->border_color=data->hover_border; } void handle_button_leave(Widget* self,int mouse_x,int mouse_y){ + (void)mouse_x; (void)mouse_y; ButtonData* data=(ButtonData*)self->data; if(!data)return; // Revert button color when not hovering data->bg_color=data->base_color; - data->border_color=data->border_color; + data->border_color=data->base_color; } + +typedef struct { + char* placeholder; + char* text; + uint32_t bg_color; + uint32_t text_color; +} TextboxData; void widget_draw(Widget* widget,FrameBuffer* fb){ if(widget&&widget->draw){ widget->draw(widget,fb); @@ -125,8 +132,19 @@ void widget_update(Widget* widget,FrameBuffer* fb){ } } void widget_handle_event(Widget* widget,int mouse_x,int mouse_y,int event){ - if(widget&&widget->handle_event){ - widget->handle_event(widget,mouse_x,mouse_y,event); + if (!widget) return; + if (mouse_x >= widget->x && mouse_x < widget->x + widget->width && + mouse_y >= widget->y && mouse_y < widget->y + widget->height) { + + if (event == EVENT_MOUSE_CLICK && widget->onClick) { + widget->onClick(widget, mouse_x, mouse_y, 1); // Assuming left button for now + } else if (event == EVENT_MOUSE_RELEASE && widget->onRelease) { + widget->onRelease(widget, mouse_x, mouse_y, 1); // Assuming left button for now + } else if (event == EVENT_MOUSE_HOVER && widget->onHover) { + widget->onHover(widget, mouse_x, mouse_y); + } else if (event == EVENT_MOUSE_MOVE && widget->onMove) { + widget->onMove(widget, mouse_x, mouse_y); + } } } void widget_add(Widget** head,Widget* new_widget){ @@ -201,9 +219,9 @@ Widget* create_label(int x,int y,int width,int height,char* text,uint32_t color) widget->data=data; widget->draw=draw_label; widget->update=update_label; - return widget; + return widget; } -Widget* create_button(int x,int y,int width,int height,char* text,uint32_t base_color,uint32_t hover_color,uint32_t press_color,uint32 _t border_color,int border_width,uint32_t text_color,uint32_t press_border,uint32_t hover_border){ +Widget* create_button(int x,int y,int width,int height,char* text,uint32_t base_color,uint32_t hover_color,uint32_t press_color,uint32_t border_color,int border_width,uint32_t text_color,uint32_t press_border,uint32_t hover_border){ ButtonData* data=(ButtonData*)malloc(sizeof(ButtonData)); if(!data)return NULL; data->text=text; @@ -231,7 +249,7 @@ Widget* create_button(int x,int y,int width,int height,char* text,uint32_t base_ widget->onRelease=handle_button_release; widget->onHover=handle_button_hover; widget->onMove=NULL; - return widget; + return widget; } Widget* create_textbox(int x,int y,int width,int height,char* placeholder,uint32_t bg_color,uint32_t text_color){ TextboxData* data=(TextboxData*)malloc(sizeof(TextboxData)); @@ -260,6 +278,13 @@ Widget* create_textbox(int x,int y,int width,int height,char* placeholder,uint32 widget->update=update_textbox; return widget; } + +typedef struct { + uint32_t bg_color; + uint32_t thumb_color; + int thumb_pos; + int thumb_size; +} ScrollbarData; Widget* create_scrollbar(int x,int y,int width,int height,uint32_t bg_color,uint32_t thumb_color){ ScrollbarData* data=(ScrollbarData*)malloc(sizeof(ScrollbarData)); if(!data)return NULL; @@ -283,15 +308,16 @@ Widget* create_scrollbar(int x,int y,int width,int height,uint32_t bg_color,uint } void init_widget_system(){ // Initialize default font - g_widget_font=load_font("default_font_path"); // Placeholder path -} - if(!g_widget_font){ - // Fallback to built-in font - g_widget_font=get_builtin_font(); - } + // g_widget_font=load_font("default_font_path"); // Placeholder path + + // if(!g_widget_font){ + // Fallback to built-in font + // g_widget_font=get_builtin_font(); + // } if(!g_widget_font){ // If still no font, log error - log_error("Failed to load widget font"); + vga_print_string("Failed to load widget font\n"); } // Initialize other widget system components if needed +} \ No newline at end of file diff --git a/widget.h b/widget.h index e91a3a1..71c2c75 100644 --- a/widget.h +++ b/widget.h @@ -9,14 +9,12 @@ typedef enum { WIDGET_BUTTON, WIDGET_CHECKBOX, WIDGET_RADIOBUTTON, - WIDGET_SLIDER, WIDGET_SCROLLBAR, WIDGET_LISTBOX, WIDGET_PANEL, WIDGET_TEXTBOX, WIDGET_TEXTAREA, WIDGET_COMBOBOX, - WIDGET_MENU, WIDGET_TABLE, WIDGET_TREE, WIDGET_GRAPH, @@ -31,7 +29,8 @@ typedef enum { WIDGET_MENU, WIDGET_TOGGLEBUTTON, WIDGET_RADIOGROUP, - WIDGET_VOICEINPUT + WIDGET_VOICEINPUT, + WIDGET_WINDOW }WidgetType; typedef enum { @@ -72,11 +71,22 @@ typedef struct{ uint32_t hover_color; uint32_t hover_border; } ButtonData; -//Below are the constructors. +void init_widget_system(void); +void widget_set_font(Font* font); +void widget_draw_all(Widget* head,FrameBuffer* fb); +void widget_update_all(Widget* head,FrameBuffer* fb); +void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event); +void widget_add(Widget** head,Widget* new_widget); +void widget_remove(Widget** head,Widget* widget); +void widget_free(Widget* widget); +void widget_free_all(Widget** head); +void widget_update(Widget* widget,FrameBuffer* fb); +void widget_handle_event(Widget* widget,int mouse_x,int mouse_y,int event); + Widget* create_label(int x,int y,int width,int height,char* text,uint32_t color); -//Widget* create_button(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width,uint32_t base_color,int base_width,uint32_t text_color,uint32_t press_color,uint32_t press_border,uint32_t hover_color,uint32_t hover_border); -Widget* create_button(int x, int y, int w, int h, char* text, - uint32_t text_color, uint32_t base_color, uint32_t border_color); +Widget* create_textbox(int x,int y,int width,int height,char* placeholder,uint32_t bg_color,uint32_t text_color); +Widget* create_scrollbar(int x,int y,int width,int height,uint32_t bg_color,uint32_t thumb_color); +Widget* create_button(int x,int y,int width,int height,char* text,uint32_t base_color,uint32_t hover_color,uint32_t press_color,uint32_t border_color,int border_width,uint32_t text_color,uint32_t press_border,uint32_t hover_border); void widget_draw(Widget* widget, FrameBuffer* fb); //Widget* create_checkbox(int x,int y,int width,int height,char* text,uint32_t color,uint32_t bg_color,uint32_t border_color,int border_width); diff --git a/widget.o b/widget.o new file mode 100644 index 0000000000000000000000000000000000000000..5efa96919385a76fec76a314a2fa54e6fe67943b GIT binary patch literal 6580 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 ziichar_height; int text_x=window->x+window->width/2-text_width/2; int text_y=window->y+(TITLE_BAR_HEIGHT-text_height)/2; - draw_string(fb,text_x,text_y,window->title,TITLE_TEXT_COLOR,g_widget_font); + draw_string(fb,g_widget_font,window->title,text_x,text_y,TITLE_TEXT_COLOR); } // Draw close button @@ -128,10 +127,12 @@ void window_handle_event(Window* window,int mouse_x,int mouse_y,int event){ widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,event); } void window_on_click(Window* window,int mouse_x,int mouse_y,int button){ + (void)button; if(!window)return; widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_CLICK); } void window_on_release(Window* window,int mouse_x,int mouse_y,int button){ + (void)button; if(!window)return; widget_handle_event_all(window->child_widgets_head,mouse_x,mouse_y,EVENT_MOUSE_RELEASE); } @@ -270,24 +271,11 @@ void window_manager_handle_mouse(Window** head, Window** tail, int32_t mouse_x, spinlock_release(&wm_lock); } -void widget_update_all(Widget* head,FrameBuffer* fb){ - Widget* current=head; - while(current){ - widget_update(current,fb); - current=current->next; - } -} -void widget_handle_event_all(Widget* head,int mouse_x,int mouse_y,int event){ - Widget* current=head; - while(current){ - widget_handle_event(current,mouse_x,mouse_y,event); - current=current->next; - } -} void wm_process_mouse(int mouse_x,int mouse_y,uint8_t mouse_buttons,uint8_t last_buttons){ window_manager_handle_mouse(&window_list_head,&window_list_tail,mouse_x,mouse_y,mouse_buttons,last_buttons); } void window_handle_key(char key){ + (void)key; if(!window_list_tail)return; // For now, just a placeholder to show where key handling would go. // In a real implementation, you'd route this to the focused window's widgets. diff --git a/window.h b/window.h index 93e6767..092dd33 100644 --- a/window.h +++ b/window.h @@ -14,6 +14,7 @@ typedef struct Window { bool close_button_hovered; }Window; +void window_manager_init(void); Window* create_window(int x,int y,int width,int height,const char* title,bool has_title_bar); void window_add_widget(Window* window,Widget* widget); void window_remove_widget(Window* window,Widget* widget); diff --git a/window.o b/window.o new file mode 100644 index 0000000000000000000000000000000000000000..97b6f5af63b5a70addc53acf20dbee1fd436e645 GIT binary patch literal 6632 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 literal 0 HcmV?d00001 From de60523748d141faddb23b8fafadb949073e5e56 Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 17 Dec 2025 01:20:33 +0530 Subject: [PATCH 17/18] Add files via upload --- Makefile | 26 ++++---- boot.asm | 161 +++++++++++++++++++++++++++++++++++-------------- boot.bin | Bin 512 -> 512 bytes console.c | 38 +++++++----- console.h | 1 + console.o | Bin 1109 -> 1871 bytes create_iso.sh | 2 +- floppy.img | Bin 1474560 -> 1474560 bytes gdt.c | 2 +- graphics.h | 24 ++++---- heap.c | 18 +++--- heap.o | Bin 1332 -> 1496 bytes idt.c | 73 ++++++++++++++++++---- interrupt.o | Bin 1716 -> 1716 bytes kernel.bin | Bin 1115400 -> 1115412 bytes kernel.c | 87 +++++++++++--------------- kernel.elf | Bin 55593 -> 54908 bytes kernel.o | Bin 5458 -> 4923 bytes kernel.tmp | Bin 0 -> 53093 bytes kernel_entry.o | Bin 238 -> 238 bytes keyboard.c | 4 +- mouse.h | 2 +- mutex.o | Bin 1465 -> 1265 bytes os-image.bin | Bin 1115912 -> 1115924 bytes os.img | Bin 0 -> 42772 bytes paging.c | 10 +-- spinlock.h | 7 +-- sync.h | 28 ++++++++- task.c | 7 ++- task.h | 2 +- task.o | Bin 2220 -> 2143 bytes widget.c | 22 +------ widget.o | Bin 6580 -> 6534 bytes 33 files changed, 316 insertions(+), 198 deletions(-) create mode 100644 kernel.tmp create mode 100644 os.img diff --git a/Makefile b/Makefile index f2d55a9..d2a1cbd 100644 --- a/Makefile +++ b/Makefile @@ -1,42 +1,40 @@ -CC = i686-w64-mingw32-gcc -LD = i686-w64-mingw32-ld -OBJCOPY = i686-w64-mingw32-objcopy +CC = gcc +LD = ld +OBJCOPY = objcopy NASM = nasm -CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. + +CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. -std=gnu99 +# Use -f win32 for MinGW, -f elf32 for Linux/Cross-Compiler +NASMFLAGS = -f win32 +LDFLAGS = -T linker.ld # Auto-detect all .c files in the current folder C_SOURCES = $(wildcard *.c) +# Exclude spinlock.c if it exists (replaced by sync.h implementation) +C_SOURCES := $(filter-out spinlock.c, $(C_SOURCES)) # Create a list of .o files to build OBJ = $(C_SOURCES:.c=.o) # Default target all: os.img -# 1. Create the Disk Image (Boot + Kernel) os.img: boot.bin kernel.bin cat boot.bin kernel.bin > os.img -# 2. Compile the Bootloader (Flat Binary) boot.bin: boot.asm $(NASM) -f bin boot.asm -o boot.bin -# 3. Compile the Kernel (Binary extraction) kernel.bin: kernel.tmp $(OBJCOPY) -O binary kernel.tmp kernel.bin -# 4. Link the Kernel (at 1MB) -# Note: interrupt.o must be linked! kernel.tmp: $(OBJ) interrupt.o - $(LD) -Ttext 0x100000 -o kernel.tmp $(OBJ) interrupt.o + $(LD) $(LDFLAGS) -o kernel.tmp $(OBJ) interrupt.o -# 5. Compile Assembly Stub (Interrupts) interrupt.o: interrupt.asm - $(NASM) -f win32 interrupt.asm -o interrupt.o + $(NASM) $(NASMFLAGS) interrupt.asm -o interrupt.o -# 6. Compile C Files %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ -# Clean clean: rm -f *.o *.bin *.tmp os.img \ No newline at end of file diff --git a/boot.asm b/boot.asm index ce09ab3..5049190 100644 --- a/boot.asm +++ b/boot.asm @@ -1,7 +1,7 @@ bits 16 org 0x7c00 -; --- Memory Definitions (NOT File Space) --- +; --- Memory Definitions --- VBE_INFO_BLOCK equ 0x9000 MODE_INFO_BLOCK equ 0x9200 @@ -15,12 +15,12 @@ TARGET_HEIGHT equ 720 TARGET_BPP equ 32 ; Kernel placement -KERNEL_TEMP_ADDR equ 0x1000 ; Segment 0x1000 (Physical 0x10000) -KERNEL_TARGET_ADDR equ 0x100000 ; 1MB -SECTORS_TO_READ equ 100 ; Read 50KB +KERNEL_TEMP_ADDR equ 0x1000 +KERNEL_TARGET_ADDR equ 0x100000 +SECTORS_TO_READ equ 100 start: - jmp 0:init_segments ; Far jump to normalize CS + jmp 0:init_segments init_segments: xor ax, ax @@ -29,12 +29,16 @@ init_segments: mov ss, ax mov sp, 0x7c00 - mov [boot_drive], dl ; Save the boot drive number provided by BIOS + mov [boot_drive], dl ; Save boot drive - ; 1. Load Kernel from Disk to Temp Buffer - call load_kernel + ; 1. Load Kernel (Fixed Routine) + call load_kernel_safe + + ; CRITICAL FIX: Ensure ES is 0 for VBE calls + xor ax, ax + mov es, ax - ; 2. Enable A20 Line + ; 2. Enable A20 in al, 0x92 or al, 2 out 0x92, al @@ -46,76 +50,146 @@ init_segments: cmp ax, 0x004F jne .graphics_error - mov cx, [VBE_INFO_BLOCK + 14] - mov si, [VBE_INFO_BLOCK + 16] + ; Get video modes list pointer + mov cx, [VBE_INFO_BLOCK + 14] ; Offset + mov si, [VBE_INFO_BLOCK + 16] ; Segment + mov fs, si ; Use FS to access the mode list segment + + ; Note: The list is a far pointer (Seg:Off). + ; We need to read from FS:CX (Seg:Off). + ; But for simplicity in Real Mode flat memory (if Seg is not 0), + ; we usually normalize. + ; If BIOS returns a segment for the list, we must use it. + ; Simplification: Many BIOSes return Segment in SI. + + mov si, cx ; Move Offset to SI + mov ax, [VBE_INFO_BLOCK + 16] + mov ds, ax ; Point DS to the VBE Mode List Segment .mode_loop: + mov cx, [si] ; Read mode number + cmp cx, 0xFFFF ; End of list? + je .graphics_error + push cx + + ; Restore DS to 0 for the Interrupt buffer access + push ds + xor ax, ax + mov ds, ax + mov ax, VBE_MAGIC + VBE_GET_MODE_INFO - mov cx, [si] mov di, MODE_INFO_BLOCK int 0x10 + cmp ax, 0x004F - jne .next_mode + pop ds ; Restore Mode List Segment + jne .next_mode_pop + + ; Check resolution (Need to use ES or explicit segment 0 override since DS is changed) + ; But wait, MODE_INFO_BLOCK is at 0x9200. We need to check it using DS=0. + ; It's cleaner to just switch DS back to 0 for the check. + push ds + xor ax, ax + mov ds, ax cmp word [MODE_INFO_BLOCK + 18], TARGET_WIDTH - jne .next_mode + jne .check_failed cmp word [MODE_INFO_BLOCK + 20], TARGET_HEIGHT - jne .next_mode + jne .check_failed cmp word [MODE_INFO_BLOCK + 25], TARGET_BPP - jne .next_mode + jne .check_failed + + ; FOUND IT! + pop ds ; Restore stack balance (pushed DS) + pop cx ; Restore Mode Number (pushed CX) + jmp .set_mode + +.check_failed: + pop ds +.next_mode_pop: + pop cx + add si, 2 + jmp .mode_loop + +.set_mode: + ; CX holds the mode number + mov bx, cx + or bx, 1 << 14 ; Linear Frame Buffer bit + + ; Reset DS to 0 before final call + xor ax, ax + mov ds, ax - ; Found mode! Set it. mov ax, VBE_MAGIC + VBE_SET_MODE - mov bx, [si] - or bx, 1 << 14 int 0x10 cmp ax, 0x004F jne .graphics_error - + ; Save VBE info for kernel - push es + ; Copy from 0x9200 (MODE_INFO_BLOCK) to 0x8000 xor ax, ax mov es, ax + mov ds, ax mov edi, 0x8000 mov esi, MODE_INFO_BLOCK - mov ecx, 256 - rep movsb - pop es + mov ecx, 64 ; Copy 256 bytes (64 dwords) + rep movsd ; Use movsd for speed (32-bit width in 16-bit mode needs 0x66 prefix usually, but `rep movsd` works in real mode on 386+) - ; FIX: Jump to the global label (no dot) jmp enter_pm -.next_mode: - add si, 2 - pop cx - loop .mode_loop - .graphics_error: cli hlt -; --- Disk Loading Routine --- -load_kernel: +; --- Safe Disk Loading (CHS Loop) --- +load_kernel_safe: mov ax, KERNEL_TEMP_ADDR - mov es, ax - xor bx, bx + mov es, ax ; Buffer segment + xor bx, bx ; Buffer offset 0 + mov dl, [boot_drive] + mov ch, 0 ; Cylinder 0 + mov dh, 0 ; Head 0 + mov cl, 2 ; Start at Sector 2 + + mov si, SECTORS_TO_READ + +.read_loop: mov ah, 0x02 - mov al, SECTORS_TO_READ - mov ch, 0 - mov dh, 0 - mov cl, 2 - mov dl, [boot_drive] + mov al, 1 ; Read 1 sector at a time int 0x13 jc .disk_error + + dec si + jz .done + + add bx, 512 ; Move buffer pointer + ; Handle Segment overflow (64KB) if necessary, but 50KB fits in one segment. + + ; Update CHS + inc cl ; Next sector + cmp cl, 19 ; 18 sectors per track? + jl .read_loop + + ; Next Track/Head logic + mov cl, 1 ; Reset sector + inc dh ; Next head + cmp dh, 2 ; 2 heads? + jl .read_loop + + mov dh, 0 ; Reset head + inc ch ; Next cylinder + jmp .read_loop + +.done: ret .disk_error: cli hlt -; --- Protected Mode Entry (Global Label) --- +; --- Protected Mode Entry --- enter_pm: cli lgdt [gdt_descriptor] @@ -140,10 +214,9 @@ start_protected_mode: mov ecx, (SECTORS_TO_READ * 512) / 4 rep movsd - ; Jump to Kernel (1MB) - push dword 0x8000 - mov eax, KERNEL_TARGET_ADDR - call eax + ; Jump to Kernel + ; Ensure kernel_entry.o is linked FIRST + jmp KERNEL_TARGET_ADDR cli hlt diff --git a/boot.bin b/boot.bin index a7532c8be10f801f250d6e0a4d8174d5bf134a68..29b9bcefc5474a4489da0bee742d2eaab5ae5d2e 100644 GIT binary patch delta 290 zcmZo*X<(^;#ahF_V0fVKM&E(H3ws!9I>d}>U(5%I9C$K`hw0g*9sUga877<+X#U~P z-`c{^&Br&P+e~0W-?Pqh3xU*)Zl30!|4VWLvz_E5g;Eyz$k*)hk5 aQDc31p^2Yi;yXnqbKIyeMOMGKq)j*`yu*4Eq@-oE2#P;a{5A z&Br&P+e~0W;En)>Zl3)NlOW>Gjdntl7+6cK8|_3UU0^CTZnl%0q)@7}Baoq6rtvg` z14Nk;8_<#iY5N%(7#Py_F-!uII~f=mY#BZ;VSlaCe2gjb(ehtkb}$I^9WcDTg=s^| zR)%d18=1O*&N(Yw#CZ7EmtXvhV!XBd3J21fPcZT;9eA~`W-=?I8cznu$Q=v}0u28z XOg3OtWcpY$IgxShchar_height; + // Simple scrolling + if (cursor_y + console_font->char_height > console_fb->height) { + // This would require a memcpy-like function to move screen contents up. + // For now, we'll just wrap around. + cursor_y = 0; + } continue; } + draw_char(console_fb, console_font, c, cursor_x, cursor_y, 0xFFFFFF); + cursor_x += console_font->char_width; if (cursor_x + console_font->char_width > console_fb->width) { cursor_x = 0; @@ -25,17 +34,18 @@ void console_write(const char* str) { } } } -#undef console_fb -#undef console_font -#undef console_write -#define console_init console_init -#define console_write console_write -#define console_fb console_fb -#define console_font console_font -#define console_write console_write -#define console_init console_init -#define console_fb console_fb -#define console_font console_font -#define console_write console_write -#define console_init console_init -#define console_fb console_fb \ No newline at end of file + +void console_write_dec(uint32_t n) { + if (n == 0) { + console_write("0"); + return; + } + char buf[11]; + char* p = &buf[10]; + *p = '\0'; + do { + *--p = '0' + (n % 10); + n /= 10; + } while (n > 0); + console_write(p); +} \ No newline at end of file diff --git a/console.h b/console.h index 939693e..8df9832 100644 --- a/console.h +++ b/console.h @@ -5,4 +5,5 @@ #include void console_init(FrameBuffer* fb, Font* font); void console_write(const char* str); +void console_write_dec(uint32_t n); #endif // CONSOLE_H \ No newline at end of file diff --git a/console.o b/console.o index 2de7e666762682500c932be4838142a35ce946ca..01ef4fcdc6557513fdf632caf8ccd5dd026ac907 100644 GIT binary patch literal 1871 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 kmsm2qPf-n&b2Gddp7$A>F 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 ZkYJ!;Kp{Y(Kw$@hhlJl)1^bcW{{Wm9UAq7P diff --git a/gdt.c b/gdt.c index 62f9b0d..2952465 100644 --- a/gdt.c +++ b/gdt.c @@ -30,7 +30,7 @@ void gdt_install(void) { extern void gdt_flush_asm(void); void gdt_flush(void) { - asm volatile ( + __asm__ __volatile__ ( "lgdt %0\n\t" "mov $0x10, %%ax\n\t" "mov %%ax, %%ds\n\t" diff --git a/graphics.h b/graphics.h index 99beb9a..a006221 100644 --- a/graphics.h +++ b/graphics.h @@ -1,27 +1,29 @@ #ifndef GRAPHICS_H #define GRAPHICS_H #include -typedef struct __attribute__((packed)){ +typedef struct { uint16_t attributes; - uint8_t windowA, windowB; + uint8_t windowA, windowB; uint16_t granularity; uint16_t windowSize; uint16_t windowASegment, windowBSegment; uint32_t winFuncPtr; uint16_t pitch; uint16_t resolution_x, resolution_y; - uint8_t wChar, yChar, planes, bitsPerPixel,banks; - uint8_t memoryModel, bankSize, imagePages; - uint8_t reserved1; - uint8_t redMask, redMaskPosition; - uint8_t greenMask, greenMaskPosition; - uint8_t blueMask, blueMaskPosition; - uint8_t rsvdMask, rsvdMaskPosition; - uint8_t directColorAttributes; - uint32_t physbase; + uint8_t wChar, yChar, planes, bitsPerPixel, banks; + uint8_t memoryModel, bankSize, imagePages; + uint8_t reserved1; + uint8_t redMask, redMaskPosition; + uint8_t greenMask, greenMaskPosition; + uint8_t blueMask, blueMaskPosition; + uint8_t rsvdMask, rsvdMaskPosition; + uint8_t directColorAttributes; + uint32_t physbase; uint32_t reserved2; uint16_t reserved3; } VbeModeInfo; + +extern VbeModeInfo vbe_mode_info; typedef struct{ void* address; uint32_t width; diff --git a/heap.c b/heap.c index 2704382..ff5c5c5 100644 --- a/heap.c +++ b/heap.c @@ -9,7 +9,7 @@ typedef struct heap_segment_header{ bool free; struct heap_segment_header* next; struct heap_segment_header* prev; -} __attribute__((packed)) heap_header_t; +}heap_header_t; static void* heap_start_address = NULL; static size_t heap_size = 0; @@ -110,12 +110,10 @@ void heap_free(void* ptr){ spinlock_release(&heap_lock); } -#undef heap_start_address -#undef heap_size -#undef first_segment -#undef heap_init -#undef heap_alloc -#undef heap_free -#undef heap_header_t -#define kmalloc(size) heap_alloc(size) -#define kfree(ptr) heap_free(ptr) +void* kmalloc(size_t size) { + return heap_alloc(size); +} + +void kfree(void* ptr) { + heap_free(ptr); +} diff --git a/heap.o b/heap.o index 7e3d6943678804a89b37559252f260149fba9e85..3d6f21da9e754f60ad022c26af62adc5a1945c56 100644 GIT binary patch delta 579 zcmdnOb%UGNhmn;51okmAFi1?~73W&O$iQ$1C}6`pQLl)xX5vC+jVVCx3MK}I9-tZ! z0O@dGFmUJ&QQ_!zQDJHRC0?f0{7Piv8)*(6kb>h50+aa}W5Rh_50t(!Ja7zRMfBkb zy-^aDH;XLN`12fiG%o_F6TLA4BF!&Fjx$$;nFyuvCmrncW=Z3}=FHRW!E?-+gR%8w z33F$pKxYI`X8_AF2M&hj10s_TG3wMuHCDa>=_w8DcKmV7@e5043Ra1K)H82y{FC0di!(D#d`xdV@t6f$9T)bO!LWUIJR? zBmj4B+62AcEovYiz1;op|Nq`H1~{K1`v3p`6M$fHC{urZ8%T{KA4fA2Q_EpK76t(z zw*ZJ+fPo3|JOfy)1t>NJNlXyP7Xo5725~qm9L`FCvu40qFW@Y8pg9n|`DSpY0#KR{ zh(#Do;H(HZs|3#K0I?>=GH({(0fnfqz YaIyf41mo1nnk@aSpaj7>c`r*j0K7kml>h($ delta 473 zcmcb?y@iX{hmn;51d^B;7(^!WigPtEGBDf$3VdOjs8_@oGjXA^Mh=kM!NkDe0#pM6 zAj*Nkz@a-tg`?X=g{AqINSRjiE5V6xq&YZ23XVJQPUdHf3FmA*Q2NI3z%hsw(T6AW zMu}S9EV4-B&vW3^ya=RD^u`DXHop`+&Rh{@B9z9TbgcmZhH+ L6iv*N6IsgvJ*#%U diff --git a/idt.c b/idt.c index 42eafcf..3bd315e 100644 --- a/idt.c +++ b/idt.c @@ -1,18 +1,16 @@ #include "idt.h" #include "vga.h" #include "syscall.h" - -// [FIX] Use aligned definitions if possible, but packed struct is fine. static struct idt_entry idt[256]; static struct idt_ptr ip; static inline void outb(uint16_t port, uint8_t val) { - asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); + __asm__ __volatile__("outb %0, %1" : : "a"(val), "Nd"(port)); } -static inline uint8_t inb(uint16_t port) { +static __inline__ uint8_t inb(uint16_t port) { uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + __asm__ __volatile__("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } @@ -27,6 +25,59 @@ static const char *exception_messages[] = { "Reserved", "Reserved", "Reserved", "Reserved" }; +// External Assembly ISR handlers +extern void isr0(void); +extern void isr1(void); +extern void isr2(void); +extern void isr3(void); +extern void isr4(void); +extern void isr5(void); +extern void isr6(void); +extern void isr7(void); +extern void isr8(void); +extern void isr9(void); +extern void isr10(void); +extern void isr11(void); +extern void isr12(void); +extern void isr13(void); +extern void isr14(void); +extern void isr15(void); +extern void isr16(void); +extern void isr17(void); +extern void isr18(void); +extern void isr19(void); +extern void isr20(void); +extern void isr21(void); +extern void isr22(void); +extern void isr23(void); +extern void isr24(void); +extern void isr25(void); +extern void isr26(void); +extern void isr27(void); +extern void isr28(void); +extern void isr29(void); +extern void isr30(void); +extern void isr31(void); +extern void isr128(void); + +// External Assembly IRQ handlers +extern void irq0(void); +extern void irq1(void); +extern void irq2(void); +extern void irq3(void); +extern void irq4(void); +extern void irq5(void); +extern void irq6(void); +extern void irq7(void); +extern void irq8(void); +extern void irq9(void); +extern void irq10(void); +extern void irq11(void); +extern void irq12(void); +extern void irq13(void); +extern void irq14(void); +extern void irq15(void); + void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt[num].base_lo = base & 0xFFFF; idt[num].base_hi = (base >> 16) & 0xFFFF; @@ -56,8 +107,8 @@ void isr_handler(registers_t *r) { } // Loop forever on exception - asm volatile("cli"); - for(;;) { asm volatile("hlt"); } + __asm__ __volatile__("cli"); + for(;;) { __asm__ __volatile__("hlt"); } } } @@ -155,16 +206,16 @@ void idt_install(void) { // Syscall idt_set_gate(128, (uint32_t)isr128, 0x08, 0xEE); // Ring 3 accessible - asm volatile("lidt %0" : : "m"(ip)); - asm volatile("sti"); + __asm__ __volatile__("lidt %0" : : "m"(ip)); + __asm__ __volatile__("sti"); } void page_fault_handler(registers_t *r) { (void)r; uint32_t faulting_address; - asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); + __asm__ __volatile__("mov %%cr2, %0" : "=r" (faulting_address)); vga_print_string("Page Fault at 0x"); vga_print_hex(faulting_address); vga_print_string("\n"); - for(;;) asm volatile("hlt"); + for(;;) __asm__ __volatile__("hlt"); } \ No newline at end of file diff --git a/interrupt.o b/interrupt.o index f4e37f2b2428700de7cbbb8ae4173d132569b68c..6203da43ac46bb54961b94c158819d1eb406e120 100644 GIT binary patch delta 16 XcmdnOyM>qChmn!t#5Tu`>}%NoDR~6~ delta 16 XcmdnOyM>qChmnz?W|Hkj_O)yPCV2#o diff --git a/kernel.bin b/kernel.bin index 1c68ac117a1779bf0751063ef94ae792bd3277b7..11da8ed63e14a243545ef8c1249eac22a8777781 100644 GIT binary patch delta 7542 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 +#include #include "graphics.h" #include "vga.h" #include "idt.h" @@ -8,7 +9,6 @@ #include "timer.h" #include "paging.h" //#include "pci.h" -#include "graphics.h" #include "widget.h" #include "font.h" #include @@ -22,8 +22,8 @@ #include "heap.h" #include "console.h" #include "dirty_rect.h" -#include -#define VBE_INFO_PTR ((vbe_mode_info_t*)0x8000) +#include +#define VBE_INFO_PTR ((VbeModeInfo*)0x8000) void counter_task(){ int i=0; while(1){ @@ -33,48 +33,31 @@ void counter_task(){ Widget* widget_list_head=NULL; Window* window_list_head=NULL; Window* window_list_tail=NULL; -void on_my_button_click(){ - ButtonData* data=(ButtonData*)widget_list_head->data; +void on_my_button_click(Widget* self, int x, int y, int button){ + (void)x; (void)y; (void)button; + ButtonData* data=(ButtonData*)self->data; if(!data)return; data->bg_color=data->press_color; data->border_color=data->press_border; } -void on_my_button_release(){ - ButtonData* data=(ButtonData*)widget_list_head->data; +void on_my_button_release(Widget* self, int x, int y, int button){ + (void)x; (void)y; (void)button; + ButtonData* data=(ButtonData*)self->data; if(!data)return; data->bg_color=data->base_color; - data->border_color=data->border_color; + data->border_color=data->base_color; } -typedef struct { - uint16_t attributes; - uint8_t window_a, window_b; - uint16_t granularity; - uint16_t window_size; - uint16_t segment_a, segment_b; - uint32_t win_func_ptr; - uint16_t pitch, resolution_x, resolution_y; - uint8_t chars_x, chars_y, planes, bitsPerPixel, banks; - uint8_t memory_model, bank_size, image_pages; - uint8_t reserved0; - uint32_t physbase; -} __attribute__((packed)) vbe_mode_info_t; - -vbe_mode_info_t vbe_mode_info = {0}; +VbeModeInfo vbe_mode_info = {0}; void kernel_main(void) { gdt_install(); idt_install(); - memcpy(&vbe_mode_info, (void*)0x8000, sizeof(vbe_mode_info_t)); pmm_init(128 * 1024 * 1024); heap_init(0x00400000, 16 * 1024 * 1024); // 16 MB heap at 4 MB - vga_init(); - vga_setcolor(vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK)); - - vga_print_string("SimpleOS Kernel v1.0 [SECURED]\n"); - vga_print_string("===============================\n\n"); - syscalls_install(); - paging_install(); + memcpy(&vbe_mode_info, (void*)0x8000, sizeof(VbeModeInfo)); + + // Initialize Framebuffer and Console EARLY so we can see output FrameBuffer fb; fb.address=(void*)vbe_mode_info.physbase; fb.width=vbe_mode_info.resolution_x; @@ -85,28 +68,30 @@ void kernel_main(void) { Font my_font; my_font.char_width=8; my_font.char_height=16; - my_font.bitmap=NULL; // Assume a function to load a bitmap font + my_font.bitmap=font; // Use the font array from font.h console_init(&fb, &my_font); - asm volatile("sti"); + + console_write("SimpleOS Kernel v1.0 [SECURED]\n"); + console_write("===============================\n\n"); + syscalls_install(); + paging_install(); + __asm__ __volatile__("sti"); keyboard_install(); timer_install(); rtl8139_init(); tasking_install(); mouse_install(); cursor_init(); - create_task("shell",shell_init); - create_task("counter",counter_task); + //create_task("shell",shell_init); + //create_task("counter",counter_task); uint32_t free_mem = pmm_get_free_memory(); - vga_print_dec(free_mem / 1024); - vga_print_string(" KB\n"); + console_write("Free memory: "); + console_write_dec(free_mem / 1024); + console_write(" KB\n"); - vga_print_string("\nKernel initialization complete!\n"); - vga_print_string("Security features: Buffer overflow protection, bounds checking\n"); - vga_print_string("Starting shell...\n\n"); - if (fb.bitsPerPixel != 24) { - vga_print_string("Error: Graphics mode is not 24-bit color depth!\n"); - for(;;) { asm volatile("cli; hlt"); } - } + console_write("\nKernel initialization complete!\n"); + console_write("Starting GUI...\n\n"); + uint32_t xc = fb.width / 2; uint32_t yc = fb.height / 2; @@ -115,25 +100,23 @@ void kernel_main(void) { Window* main_window = create_window(100, 100, 400, 300, "Welcome to SimpleOS!", true); if (!main_window) { vga_print_string("Error: Failed to create main window!\n"); - for(;;) { asm volatile("cli; hlt"); } + for(;;) { __asm__ __volatile__("cli; hlt"); } } Widget* label = create_label(20, 40, 200, 30, "Hello, SimpleOS!", 0x000000); if (!label) { vga_print_string("Error: Failed to create label widget!\n"); - for(;;) { asm volatile("cli; hlt"); } + for(;;) { __asm__ __volatile__("cli; hlt"); } } Widget* button = create_button(100, 100, 100, 50, "Click Me", 0xFFFFFF, 0x0000FF, 0x000000, 0x000000, 1, 0x000000, 0x000000, 0x000000); if (!button) { vga_print_string("Error: Failed to create button widget!\n"); - for(;;) { asm volatile("cli; hlt"); } + for(;;) { __asm__ __volatile__("cli; hlt"); } } - widget_add(&widget_list_head, label); - widget_add(&widget_list_head, button); window_add_widget(main_window, label); window_add_widget(main_window, button); window_draw(main_window, &fb); - button->onClick = (void (*)(struct Widget*, int, int, int))on_my_button_click; - button->onRelease = (void (*)(struct Widget*, int, int, int))on_my_button_release; + button->onClick = on_my_button_click; + button->onRelease = on_my_button_release; window_list_head = main_window; window_list_tail = main_window; init_widget_system(); @@ -179,6 +162,6 @@ void kernel_main(void) { cursor_update(&fb, mouse_x, mouse_y); - asm volatile("hlt"); + __asm__ __volatile__("hlt"); } } diff --git a/kernel.elf b/kernel.elf index ee87775430697b4b9c1d26bc14ac600691f9df32..7eff02318f6e83d45855ae173a5995114703080f 100644 GIT binary patch delta 13215 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ⅆ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%0A3NnCJ%TA;7uV!2^tt)&lB9w72FGJumne_ zIBv6rar>5i|9Y5AhP}mV5Ylb&*cu8jQvlQHs|LqquUNbwyR`VJ?c@87#we)O^+U!1 z+0+j)1F08Gv6x05St{6@0;@PDSSIV!0dnlZ8!E-$J=g+ZS^?|yV9S6x2~*NvUd8e> zFl(F;KV5{xvI*c70aSeI0e1teV+$IEgOj(iLyb$l>uA8(lx;&X&4vEjDD;=G*gDv} zV-fhaS9L5*c9=Yy$qRerO&{4wu$>}X^rjDgo;4gBrl4z-Sm@t5XxX4QRf_+3u>S(f zB#eFWrjNHb_QQIC`vc|%gKJD+*1bW#w>=GFSo5316u)_RE0i)>0}L!_^6{PqE=S3b2$*p9 z6R`Jzacuf=6?+z~E`iGwxYxm50arqt!p~#lCtywi3-DlFf{m-NG5jqbZ-4BpnT)t( zaG~Jph*QvaL9yt7brPl=;=vvPW=#H_i>M@Y3#>$hAHNH_$Q%+!}}eTV!j6} z16D`as0ALZ7TCdl=AQ?0MQFLuqeXlBO~UAIhqIfV5^s!Gdbj_}cuNxZ-!z;N!)W{G zt60XnVY2tpICHWveq|nuodD|z4Cgah)4NOgP8N1roPT~HbaV=vR0vyqI)dNL9H%2B z&MCqGY5ykk$zGPbY+=bNE@!G>^%=oxcA2fTFt>=S6G6KOE?ZDY|9ajjfQHQ;|6jwu zvtQoVfn4z**?Fb8xtMACOpE5tKng?HsrN!3$RHuUUf|g47Cr`KXLo#}dLFy~ zo-w$*+YA)DHEVz@3Sp1Dug%^G(h8UOC%@goMpDOE^&)2l1L{7=zktwK_Uh2zjOqVg z5c45dgYaD`pMCy*Sa1ZW{xYM0Fr_o^fr%ig^yZNTq_=BGwu0?;E|qN&8~HVdKJctWwcSAa zPl2O?PG66w*qzo4S%+YarF}4A>i69$;(&#mlu@gW*3w$FI%u8 em&^7@@PGK^E+`Wu_@^zl;?mrv?>^e$^Zx+Xcs->6 diff --git a/kernel.o b/kernel.o index 0322ca826b3a42d3bce020d344e63845a54853df..f1ab543e4358ce3af7c1861da34a4ee5bb953485 100644 GIT binary patch literal 4923 zcmaJ_ZEPGz8J_d4-IKZcTyzbkb?Bzq7Kgf5J8d9#6LO9(j;khdu$?c}bhEzOvp3oM z(B9gPO=wCTw>_>#mf9aks1lI?krGO{<}sIJ@i<)1m=a=aZ$$JDpi$Z0 z!-mq)yk5!9S=Xj4lgF0)eaxTm>ChCw1B_l{SV462W@zM^QP4t z*X!7{ihLHm^UzzsT&XCiq*qC4N+sDgyXZE)8+$ydW@B$8Bj>X7iMf~WA-$@+DI3ct z1|_Xp4RUpv2N=30Ety@!?mzMRscB>C4LIF9rK&n$&ND>1-V{~SL0 z`t2KjIkVUuTUabB+B>9tb=ezl-+}#uU%N)pa(>R%4$d9d#&~C0(ZELphC6gZoJ$I2 z3=yI9&`|6Nv|L}vPPIZ%wl(FIW&&HZa!MPE{iyzv)Em-<(Y4WyqYLxHXc(v>D6XH< z+}J|>r@=mx(vB^@6Gk(2CL**B) zBh#slMMTt&+J@Q+dyS%jL`7{u|F#w3C+^LnIV_^$vw=Lqqr=i)A7y1oOU*8pmtrRe zF&Y+I@pFn6gDE^3!pA+l+}nb&*m5sl#q!$C6vG$W`eCN3hWa19=h@89=bRy4{FAEL6B9C03r=(OJ%=O*%PhwD4e}H+!O75E%uGCW3=pildLc455e94Y{8@R+wG7*uHe9QaSJMR= z&NbIHvO(8yTq{4S?%elqB9VZn1EvkRsk#N#4{IIy+Tl0_r%UZMEZfYGH0_v%i$M)5 zuTEO|OkooK`b^s{wAEVP$j&xKFw;pZGitgp?6Ix%QFXU@!*NE&T^F%SgPlD+U25xq zIkCA--9B#Ft~xTM?jAfexKS-Sg(GI#-Jo`CN^DHDGse#y%po*Az(U6(p*y0A@(dP( z-V}O?71TATREUEK(@<|mr9wI>uRcsfcT?o4x}K)!Ot`N}Wvmrc2K9N=^W+Tj*}Cqg z=+oiursk)V?xy%meQ(pZF(jKor9&^yzJ=$V9G%8f<>+NRDcx~)0nfWQdK=Fs)CP7L z&-I+UA~^=9LK>6kQ$Q4Z1G`Id_es?>H*~ZQ$q_(C0Y%D$um`hklxI_?EWKQj+-?yThA2BKp#&i)NV zw~2KFl;Vfz~?{Tt90?)jfm?*pl~2D?{`+X5tP z*8vHCZ9pP|EkIkjmjNI#?r9(~j~@UDi@rbA?=XTos!!nITd!a9&x^U0`*C5Ork^<#~FH5KEmB$G<1|7!HKls{3l)N zsDzlx>aeq_1>t&y_O^-|)Tv(4dmvAKtWE^1C|^P|j~etN13bjs2@S!KS59_?wt=-EQvMb9sFOwSd@OQwFT$`Cr^chO3nDW4Rh zFZ*4rtYF>@FqZ?&KLX5$s~8=>)ajx>l<&DgX4Yr;U7K6_%=&=NrU0`ez#IrL*#P4P znArgHe1JI>U={)loyns3vv@PWTn;er2AGgo0J!q~GzXaV0j52`qyo&L0COb3d?mnC z0?g?E^Wy;X^Ht36&=c>NHa$Jf66Tnmb&Q?GP3hv+qo?V1bRFlIwrP~0nJ$dy zUDMHBqXZpse(7{AyMgD45fd*&#?-BRw!n08chhaF3xuST5#Q znkuE?r&M)VG)8e}t@e+aQzHe#$y6EF${`~%0>`yCcRbJug8WmWR@sZmNbU5vQ!0=( zDO0>O_bhJM^xoozeO-il#!Q34YB+icw_-ET^o(On>S@aX3lYC5dx@4^egT#}kx7|* zBa`uxE-7+}Tp}ocIgl9F%t?iukvB&9tSRn{<+xM2gL|+y5pNAkG#5G`Yc()jz|EME j&tOS-ZdNH%Hu$=Fc^WU`UnxwJ?*YfkyL!n*Gs^x4m4c2g literal 5458 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 literal 0 HcmV?d00001 diff --git a/kernel_entry.o b/kernel_entry.o index 630662bbffcce41d2144c9a624137256bf3d1a9b..5354fa5914fe0733a778787575b74d1867ccd425 100644 GIT binary patch delta 15 WcmaFI_>Pg?hmn!t_%_Fh?9TxyYXxxt delta 15 WcmaFI_>Pg?hmnz?W|Hkh_U8a52Zg4wQa<0g~@L z-cZfRP~xfAyG0Ge?{?-m?(P9H=(xKNNTBsVsdr~}Jx6DW3QMPq3Rn}+s0lC)NCtvT zD&2p~nUS%xn&lWXL)hHrBLdNJ@rQd$)EHpuI}dd`_y7(4-dW}IdR5v4paX%f69Bmm z>|iAGx~o~h)>$4ebyop8to1;NRvLevhYyfA0J0{HKj~l^|21cp;|?Ame}V0USqN0X zaNHRjB(I-MfP%@KOzw&TK&3K343d)qVh}I^Vgn#n0pfX+H!_JUR&ntOI3DKXaXiMy z;dq>n#h06bK?f+C0mMguI2EW$*qO(C literal 1465 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 POU$L_G90@VxZ?g7v@d+@ delta 7963 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 EABg)`D*ylh diff --git a/os.img b/os.img new file mode 100644 index 0000000000000000000000000000000000000000..6527259835915827e2b446b6aea8a19d473544a9 GIT binary patch literal 42772 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 -#include -typedef volatile int spinlock_t; -void spinlock_init(spinlock_t* lock); -unsigned long spinlock_acquire_irqsave(spinlock_t* lock); -void spinlock_release_irqrestore(spinlock_t* lock, unsigned long flags); +#include "sync.h" #endif \ No newline at end of file diff --git a/sync.h b/sync.h index 906d91c..55a6c20 100644 --- a/sync.h +++ b/sync.h @@ -11,7 +11,7 @@ typedef struct { * @brief Initializes a spinlock to the unlocked state. * @param lock Pointer to the spinlock */ -static inline void spinlock_init(spinlock_t* lock) { +static __inline__ void spinlock_init(spinlock_t* lock) { lock->locked = 0; } @@ -20,7 +20,7 @@ static inline void spinlock_init(spinlock_t* lock) { * This uses an atomic test-and-set operation. * @param lock Pointer to the spinlock. */ -static inline void spinlock_acquire(spinlock_t* lock) { +static __inline__ void spinlock_acquire(spinlock_t* lock) { while (__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE)); } @@ -28,8 +28,30 @@ static inline void spinlock_acquire(spinlock_t* lock) { * @brief Releases the spinlock. * @param lock Pointer to the spinlock. */ -static inline void spinlock_release(spinlock_t* lock) { +static __inline__ void spinlock_release(spinlock_t* lock) { __atomic_clear(&lock->locked, __ATOMIC_RELEASE); } +/** + * @brief Acquires the spinlock and disables interrupts. + * @param lock Pointer to the spinlock. + * @return The flags register before interrupts were disabled. + */ +static __inline__ unsigned long spinlock_acquire_irqsave(spinlock_t* lock) { + unsigned long flags; + __asm__ __volatile__("pushf; pop %0; cli" : "=r"(flags)); + spinlock_acquire(lock); + return flags; +} + +/** + * @brief Releases the spinlock and restores interrupts. + * @param lock Pointer to the spinlock. + * @param flags The flags register to restore. + */ +static __inline__ void spinlock_release_irqrestore(spinlock_t* lock, unsigned long flags) { + spinlock_release(lock); + __asm__ __volatile__("push %0; popf" :: "r"(flags)); +} + #endif // SYNC_H \ No newline at end of file diff --git a/task.c b/task.c index 9f6fd18..053517f 100644 --- a/task.c +++ b/task.c @@ -4,6 +4,7 @@ #include "timer.h" #include "idt.h" #include + static task_t* current_task; static task_t* ready_queue; static int next_pid = 1; @@ -23,11 +24,11 @@ void tasking_install(void) { vga_print_string("[OK]\n"); } void schedule_from_yield(void){ - asm volatile("int $0x20"); + __asm__ __volatile__("int $0x20"); } void create_task(char* name, void (*entry_point)(void)) { (void)name; // Name is for debugging, unused for now - asm volatile("cli"); + __asm__ __volatile__("cli"); task_t* new_task = (task_t*)pmm_alloc_page(); memset(new_task, 0, sizeof(task_t)); @@ -62,7 +63,7 @@ void create_task(char* name, void (*entry_point)(void)) { new_task->next = ready_queue->next; ready_queue->next = new_task; } - asm volatile("sti"); + __asm__ __volatile__("sti"); } void schedule(registers_t* r) { diff --git a/task.h b/task.h index a7e03af..180fbe9 100644 --- a/task.h +++ b/task.h @@ -2,7 +2,7 @@ #define TASK_H #include #include "idt.h" -#include "spinlock.h" +#include "sync.h" typedef enum { TASK_RUNNING, TASK_READY, diff --git a/task.o b/task.o index 27c9f7058e891d1ac4b13c9b99e8c18aa4d249f0..1b5cefdff75446413045bcac079da5cb1c5917fa 100644 GIT binary patch delta 169 zcmZ1@cwd0mhmnl|1RPiy7!)S*it7q6F)*+&GB9YcfW;ZafRqA5K!RRMVo4%I2uy;c zMJ5LNGfGTcsLp6JaiPe>yZoF7fT9`9Kod58yZoF-fT9)53=B#ezw$FFG{2GQc2QC3bWvde(h8j{Dlb5K z&nh$@kvTkJ!i2>l%#7k9K#>hV%mTDn79{P=rx3}data; if(!data||!data->text)return; // Draw button background - for(int y=0;yheight;y++){ - for(int x=0;xwidth;x++){ - uint32_t color=data->bg_color; - if(xwidth/2){ - if(yheight/2){ - color=data->base_color; - }else{ - color=data->hover_color; - } - }else{ - if(yheight/2){ - color=data->hover_color; - }else{ - color=data->base_color; - } - } - put_pixel(fb,self->x+x,self->y+y,color); - } - } + fill_rectangle(fb, self->x, self->y, self->width, self->height, data->bg_color); // Draw button border for(int i=0;iborder_width;i++){ for(int y=i;yheight-i;y++){ diff --git a/widget.o b/widget.o index 5efa96919385a76fec76a314a2fa54e6fe67943b..95c96fd4779af27d7552560132d0931d3441e0c9 100644 GIT binary patch delta 1341 zcmZ9LUuYCp7{%|Mo!xAb-I+~xCtIz=G&{s3n(d#65;3yMuEEqlK~jlIOwt(B)@==O zp)Z;!?n;L>>hc8zp{13S_CctSeGn0iMWYdgL_~s!phAiG5;599X}9OjBtyu3xZiKi zcka1&hCA8XleONh+{MH=Qp8wO#v9D<$!ARFj3qNQhnZVCtco>=V@BHllhU9rL01(lHN;Cmj=_I~|iz zMuOT--`|7##>na zQwO8^$92>F`s?oSK%#8(Cv z^5)cXKAGMvPs}=S&e1txVzz43NZ=J(=?{m-W5c%{&t)E=-`qENJ9Xzz@=qvIaLL)^ zV62DU6x@-naJpLfA-_bA3rqPBy(?U+tws|c#T-7&%kU7TjUIn}^P)}^o&Afn7HEk@ zS{z!EG9LeiL3EZb$R0!|3vI~)?RRL87HF%`y9RB>K`%UE9;G6$zhuA6*yg!K%TNOn zf@E6fEtO_u+T;BUz5(w_p2QrYr(U;o%SnHE%lT@`S5`{5T(m~1ma=*Dr4oiIqts%- zZKbBa9y>LPKsE*X+@uh~x0+N1ihx|~6lja7rEpeDyN5$nzwb|4QLJU&+Y#IVtd4GbeBfPRHXH&5o z`&-c)fL2U1$XeWO(;=JAfvmv$HoXQ}DGvOfR*DX?QZ|Aj<^gxv-Mye4&;sm@&3~CajmSBZ7?xVCr3-KP)bHT6BOmPWahxe>dJf-ti zR?KOi{{wOb6h3a6t3lHyZ3ji@4WcV-`wm=!b~+vi@ynt^S53E|XQsPI)6}r-9)SB8 z6=@+pf?12e-j)XMoW`UTx5=tk(3R>M0fSn>}p3f`TZ!Ll_6 z5A=3*&8L+A& E0S6okVgLXD delta 1424 zcmZ9Le{2(F9LC@GdM(%W#~p2N%jTS8J;wO4;aq}gbf%cvAtD1Yh(;l5AWG&hWP-_D zF>6WQ92+g~Lc)J&zz{KkWD5o%VFTv21kJWgT_!P_nAzBXGZ}GFaX#Y%YLGpwe6gUxJTmzh)3w*{7D#?hU+{=H@VYjTq()O+6mtWv&&~yEQg}sp*9IqC7h5N-At%USNgM+0{4L z%Z6s|=6hT^P4=|9evxUGzo1;B7kPS+}5)~%)CT8@Wq{--b8cxFi@flBWZZ5OngOSBef<9wq({KT)Qlr75cMn#qh zDP5$UgJvw!)}eM4T0-V0{B^XO_xr=ey)Y!_o62#INCp?Sz%(36Cufbz11m@1In z@}Wb=Kz7Tg4qb5QItVdH`PQKskUdsNS;&hy)a=k}pp+fm1+-(%fb8Zk9lGYw6v!U1 z90%Q|$3S+<4v?L45M-z1Kyhop&z$Oc&{k*>vPKrKt0$_xBGGC7aVUxpc6nImUxkAB zj0OD!IxR>oMu)v_;dT*Pl=fMk&EX&&vFL5k&z8Gl!AwH6@l@?8c;uie} z$_nyTI~~n@d!&>nBSA`dKl=8A;udv*vVzn)$K8qi5ol3K^YE!i6}I5jqg3PDbzR%w z*uEEIDEv9S3bVGtkmaZJTH3=0^?&$yad^YN1AF&6?n)w&J#W3*((=yh^O{h^+GO8A QLV2m@!IDOt>C*E50VZBF<^TWy From f72a1978e7afe41b8437ea5c27d8fd3fd9a80a8f Mon Sep 17 00:00:00 2001 From: Aditya-B-Dhruva <131037390+Aditya-B-007@users.noreply.github.com> Date: Wed, 17 Dec 2025 15:25:23 +0530 Subject: [PATCH 18/18] Add files via upload --- Makefile | 6 ++- gdt.h | 4 +- idt.c | 38 ++++++++++------- idt.h | 5 ++- kernel.c | 64 +++++++++++++++++----------- kernel.elf | Bin 54908 -> 55752 bytes mutex.c | 12 ++---- mutex.h | 7 ++-- paging.c | 120 ++++++++++++++++++++++++++++++++++++----------------- paging.h | 29 +++++++++++-- task.c | 75 +++++++++++---------------------- task.h | 2 +- 12 files changed, 211 insertions(+), 151 deletions(-) diff --git a/Makefile b/Makefile index d2a1cbd..73be39d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ LD = ld OBJCOPY = objcopy NASM = nasm -CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. -std=gnu99 +CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -I. -std=gnu99 -MMD # Use -f win32 for MinGW, -f elf32 for Linux/Cross-Compiler NASMFLAGS = -f win32 LDFLAGS = -T linker.ld @@ -36,5 +36,7 @@ interrupt.o: interrupt.asm %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ +-include $(OBJ:.o=.d) + clean: - rm -f *.o *.bin *.tmp os.img \ No newline at end of file + rm -f *.o *.d *.bin *.tmp os.img \ No newline at end of file diff --git a/gdt.h b/gdt.h index af184d8..1a217de 100644 --- a/gdt.h +++ b/gdt.h @@ -10,12 +10,12 @@ struct gdt_entry { uint8_t access; uint8_t granularity; uint8_t base_high; -} __attribute__((packed)); +} __attribute__((packed)); // <--- THIS IS MANDATORY struct gdt_ptr { uint16_t limit; uint32_t base; -} __attribute__((packed)); +} __attribute__((packed)); // <--- THIS IS MANDATORY void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); void gdt_install(void); diff --git a/idt.c b/idt.c index 3bd315e..69fd519 100644 --- a/idt.c +++ b/idt.c @@ -1,9 +1,10 @@ #include "idt.h" #include "vga.h" #include "syscall.h" +#include static struct idt_entry idt[256]; static struct idt_ptr ip; - +static isr_t interrupt_handlers[256]; static inline void outb(uint16_t port, uint8_t val) { __asm__ __volatile__("outb %0, %1" : : "a"(val), "Nd"(port)); } @@ -113,7 +114,9 @@ void isr_handler(registers_t *r) { } static void (*irq_routines[16])(registers_t *r); - +void register_interrupt_handler(uint8_t n, isr_t handler) { + interrupt_handlers[n] = handler; +} void irq_install_handler(int irq, void (*handler)(registers_t *r)) { if (irq >= 0 && irq < 16) { irq_routines[irq] = handler; @@ -127,6 +130,16 @@ void irq_uninstall_handler(int irq) { } void irq_handler(registers_t *r) { + if (interrupt_handlers[r->int_no]) { + isr_t handler =interrupt_handlers[r->int_no]; + handler(r); + return; + } + if (r->int_no==128){ + syscall_handler(r); + return; + } + if (r->int_no < 32 || r->int_no > 47) return; void (*handler)(registers_t *r) = irq_routines[r->int_no - 32]; @@ -142,8 +155,10 @@ void irq_handler(registers_t *r) { void idt_install(void) { ip.limit = sizeof(struct idt_entry) * 256 - 1; ip.base = (uint32_t)&idt; + memset(&idt, 0, sizeof(struct idt_entry) * 256); + memset(interrupt_handlers, 0, sizeof(isr_t) * 256); + memset(irq_routines, 0, sizeof(void *) * 16); - // Zero out IDT for(int i=0; i<256; i++) idt_set_gate(i, 0, 0, 0); idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E); @@ -160,7 +175,7 @@ void idt_install(void) { idt_set_gate(11, (uint32_t)isr11, 0x08, 0x8E); idt_set_gate(12, (uint32_t)isr12, 0x08, 0x8E); idt_set_gate(13, (uint32_t)isr13, 0x08, 0x8E); - idt_set_gate(14, (uint32_t)page_fault_handler, 0x08, 0x8E); + idt_set_gate(14, (uint32_t)isr14, 0x08, 0x8E); idt_set_gate(15, (uint32_t)isr15, 0x08, 0x8E); idt_set_gate(16, (uint32_t)isr16, 0x08, 0x8E); idt_set_gate(17, (uint32_t)isr17, 0x08, 0x8E); @@ -184,7 +199,9 @@ void idt_install(void) { outb(0x21, 0x20); outb(0xA1, 0x28); outb(0x21, 0x04); outb(0xA1, 0x02); outb(0x21, 0x01); outb(0xA1, 0x01); - outb(0x21, 0x0); outb(0xA1, 0x0); + //outb(0x21, 0x0); outb(0xA1, 0x0); + outb(0x21,0xFF); outb(0xA1,0xFF); // Mask all IRQs initially + idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E); idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E); @@ -207,15 +224,4 @@ void idt_install(void) { idt_set_gate(128, (uint32_t)isr128, 0x08, 0xEE); // Ring 3 accessible __asm__ __volatile__("lidt %0" : : "m"(ip)); - __asm__ __volatile__("sti"); -} - -void page_fault_handler(registers_t *r) { - (void)r; - uint32_t faulting_address; - __asm__ __volatile__("mov %%cr2, %0" : "=r" (faulting_address)); - vga_print_string("Page Fault at 0x"); - vga_print_hex(faulting_address); - vga_print_string("\n"); - for(;;) __asm__ __volatile__("hlt"); } \ No newline at end of file diff --git a/idt.h b/idt.h index 10984c9..1ce5f3b 100644 --- a/idt.h +++ b/idt.h @@ -22,14 +22,15 @@ typedef struct registers { uint32_t int_no, err_code; uint32_t eip, cs, eflags, useresp, ss; } registers_t; - +typedef void (*isr_t)(registers_t *); void idt_install(void); void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags); void irq_handler(registers_t *r); void isr_handler(registers_t *r); void irq_install_handler(int irq, void (*handler)(registers_t *r)); void page_fault_handler(registers_t *r); - +void register_interrupt_handler(uint8_t n, isr_t handler); +extern void isr14(void); extern void irq0(void); extern void irq1(void); extern void irq2(void); diff --git a/kernel.c b/kernel.c index 8bde58e..2bb52f5 100644 --- a/kernel.c +++ b/kernel.c @@ -54,10 +54,11 @@ void kernel_main(void) { gdt_install(); idt_install(); pmm_init(128 * 1024 * 1024); + paging_install(); heap_init(0x00400000, 16 * 1024 * 1024); // 16 MB heap at 4 MB memcpy(&vbe_mode_info, (void*)0x8000, sizeof(VbeModeInfo)); - // Initialize Framebuffer and Console EARLY so we can see output + // Initialize Framebuffer and Console FrameBuffer fb; fb.address=(void*)vbe_mode_info.physbase; fb.width=vbe_mode_info.resolution_x; @@ -65,25 +66,26 @@ void kernel_main(void) { fb.pitch=vbe_mode_info.pitch; fb.bitsPerPixel=vbe_mode_info.bitsPerPixel; fb.bytesPerPixel = vbe_mode_info.bitsPerPixel / 8; + Font my_font; my_font.char_width=8; my_font.char_height=16; my_font.bitmap=font; // Use the font array from font.h + console_init(&fb, &my_font); console_write("SimpleOS Kernel v1.0 [SECURED]\n"); console_write("===============================\n\n"); + syscalls_install(); - paging_install(); - __asm__ __volatile__("sti"); - keyboard_install(); timer_install(); + keyboard_install(); + __asm__ __volatile__("sti"); rtl8139_init(); tasking_install(); mouse_install(); cursor_init(); - //create_task("shell",shell_init); - //create_task("counter",counter_task); + uint32_t free_mem = pmm_get_free_memory(); console_write("Free memory: "); console_write_dec(free_mem / 1024); @@ -92,56 +94,70 @@ void kernel_main(void) { console_write("\nKernel initialization complete!\n"); console_write("Starting GUI...\n\n"); - uint32_t xc = fb.width / 2; - uint32_t yc = fb.height / 2; + // --- GUI INITIALIZATION FIXES --- + + // 1. Initialize Managers & Fonts FIRST + init_widget_system(); + window_manager_init(); + dirty_rect_init(); + widget_set_font(&my_font); // Set font BEFORE creating/drawing widgets + + // 2. Clear Screen + clear_screen(&fb, 0xECECEC); // Use a nice gray background instead of black - clear_screen(&fb, 0x000000); - draw_circle(&fb, xc, yc, 50, 0xFFFFFF); + // 3. Create Window Window* main_window = create_window(100, 100, 400, 300, "Welcome to SimpleOS!", true); if (!main_window) { - vga_print_string("Error: Failed to create main window!\n"); + console_write("Error: Failed to create main window!\n"); // [FIX] Use console_write for(;;) { __asm__ __volatile__("cli; hlt"); } } + + // 4. Create Widgets Widget* label = create_label(20, 40, 200, 30, "Hello, SimpleOS!", 0x000000); if (!label) { - vga_print_string("Error: Failed to create label widget!\n"); + console_write("Error: Failed to create label widget!\n"); // [FIX] Use console_write for(;;) { __asm__ __volatile__("cli; hlt"); } } + Widget* button = create_button(100, 100, 100, 50, "Click Me", 0xFFFFFF, 0x0000FF, 0x000000, 0x000000, 1, 0x000000, 0x000000, 0x000000); if (!button) { - vga_print_string("Error: Failed to create button widget!\n"); + console_write("Error: Failed to create button widget!\n"); // [FIX] Use console_write for(;;) { __asm__ __volatile__("cli; hlt"); } } + + // 5. Assemble UI window_add_widget(main_window, label); window_add_widget(main_window, button); - window_draw(main_window, &fb); + button->onClick = on_my_button_click; button->onRelease = on_my_button_release; + window_list_head = main_window; window_list_tail = main_window; - init_widget_system(); - window_manager_init(); - dirty_rect_init(); - widget_set_font(&my_font); - //Scheduler takes over, chillax!! + + // 6. Initial Draw + window_draw(main_window, &fb); + dirty_rect_add(0, 0, fb.width, fb.height); uint8_t last_buttons = 0; int32_t last_x = -1, last_y = -1; - dirty_rect_add(0, 0, fb.width, fb.height); + // Main Loop while(1) { bool mouse_moved = (mouse_x != last_x || mouse_y != last_y); bool buttons_changed = (mouse_buttons != last_buttons); if (mouse_moved || buttons_changed) { - dirty_rect_add(last_x, last_y, 16, 16); + // Redraw only affected areas + dirty_rect_add(last_x, last_y, 16, 16); // Old cursor pos window_manager_handle_mouse(&window_list_head, &window_list_tail, mouse_x, mouse_y, mouse_buttons, last_buttons); - dirty_rect_add(mouse_x, mouse_y, 16, 16); + dirty_rect_add(mouse_x, mouse_y, 16, 16); // New cursor pos last_x = mouse_x; last_y = mouse_y; last_buttons = mouse_buttons; } + int dirty_count; const Rect* rects = dirty_rect_get_all(&dirty_count); @@ -150,6 +166,7 @@ void kernel_main(void) { const Rect* dirty = &rects[i]; Window* current = window_list_head; while (current) { + // Simple AABB collision check to see if window needs update if (!(current->x > dirty->x + dirty->width || current->x + current->width < dirty->x || current->y > dirty->y + dirty->height || current->y + current->height < dirty->y)) { window_draw(current, &fb); @@ -161,7 +178,6 @@ void kernel_main(void) { } cursor_update(&fb, mouse_x, mouse_y); - __asm__ __volatile__("hlt"); } -} +} \ No newline at end of file diff --git a/kernel.elf b/kernel.elf index 7eff02318f6e83d45855ae173a5995114703080f..3d0de9c039507c9e64904c19c6e46b9c421e7f25 100644 GIT binary patch delta 16768 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//Initializing the guard mutex->locked = false; @@ -27,12 +28,7 @@ void mutex_lock(mutex_t* mutex){ } temp->next = current; } - - // Release the spinlock and schedule another task. - // This must be atomic. schedule_and_release_lock(&mutex->lock, flags); - - // When we wake up, re-acquire the spinlock to re-check the mutex state. flags = spinlock_acquire_irqsave(&mutex->lock); } @@ -50,10 +46,8 @@ void mutex_unlock(mutex_t* mutex){ } task_t* next_task=mutex->wait_queue;//dequeue the next waiting task if (next_task!=NULL){ - mutex->wait_queue=next_task->next; - mutex->locked = true; // The lock remains held, just transferred - mutex->owner=next_task; - next_task->state=TASK_READY; + mutex->wait_queue = next_task->next; // Remove from queue + next_task->state = TASK_READY; // Corrected: TASK_READY is defined in task.h } else{ mutex->locked=false; diff --git a/mutex.h b/mutex.h index f49257a..347e070 100644 --- a/mutex.h +++ b/mutex.h @@ -1,13 +1,14 @@ #ifndef MUTEX_H #define MUTEX_H -#include "task.h" #include "spinlock.h" #include +struct task; + typedef struct mutex { spinlock_t lock; // Spinlock in order to ensure that the atomic operations on the mutex itself are thread-safe bool locked;// This is for checking if the mutex is currrently being held or not - task_t* owner;//The task that currently holds the lock - task_t* wait_queue;//A linked list of tasks waiting for the lock. + struct task* owner;//The task that currently holds the lock + struct task* wait_queue;//A linked list of tasks waiting for the lock. } mutex_t; //Function prototypes for the mutexes operations we would be defining void mutex_init(mutex_t* mutex); diff --git a/paging.c b/paging.c index 1472a74..f686678 100644 --- a/paging.c +++ b/paging.c @@ -1,47 +1,93 @@ -#include #include "paging.h" +#include "pmm.h" #include "vga.h" -//Static allocation currently, 4MB=4096-byte aligned -__attribute__((__aligned__(4096))) pt_entry_t page_directory[1024]; -__attribute__((__aligned__(4096))) pt_entry_t fpage_table[1024]; +#include +#include "idt.h" +#include "graphics.h" +struct VbeInfoBlock { + uint16_t attributes; + uint8_t windowA, windowB; + uint16_t granularity; + uint16_t windowSize; + uint16_t segmentA, segmentB; + uint32_t winFuncPtr; + uint16_t pitch; + uint16_t width, height; + uint8_t wChar, yChar, planes, bpp, banks; + uint8_t memory_model, bank_size, image_pages; + uint8_t reserved0; + uint8_t red_mask, red_position; + uint8_t green_mask, green_position; + uint8_t blue_mask, blue_position; + uint8_t rsv_mask, rsv_position; + uint8_t directcolor_attributes; + uint32_t physbase; // <--- This is what we need! + uint32_t reserved1; + uint16_t reserved2; +} __attribute__((packed)); -void paging_install(void) { - vga_print_string("Installing paging... "); - - // Verify page directory and table are properly aligned (4KB boundary) - if ((uint32_t)page_directory & 0xFFF) { - vga_print_string("[FAILED - Directory not aligned]\n"); - return; - } - if ((uint32_t)fpage_table & 0xFFF) { - vga_print_string("[FAILED - Table not aligned]\n"); - return; - } +page_directory_t* page_directory = 0; - // Initialize page directory - clear all entries first - for (int i = 0; i < 1024; i++) { - page_directory[i] = 0; - } +void paging_map(uint32_t phys, uint32_t virt, uint32_t flags) { + (void)flags; + uint32_t pd_index = virt >> 22; + uint32_t pt_index = (virt >> 12) & 0x03FF; - // Set up first page table for identity mapping (first 4MB) - for (int i = 0; i < 1024; i++) { - // Present, Read/Write, Kernel-mode, Frame address - fpage_table[i] = (i * 0x1000) | 3; // 0x1000 = 4KB, 3 = Present + Read/Write + if (!page_directory->tables[pd_index]) { + // Allocate a new page table + page_table_t* new_table = (page_table_t*)pmm_alloc_page(); + memset(new_table, 0, sizeof(page_table_t)); + + // Register it in the directory + page_directory->tables[pd_index] = new_table; + // The physical address of the new table is just its pointer (in identity map) + page_directory->physical_tables[pd_index] = ((uint32_t)new_table) | 0x7; // Present, RW, User } - // Install first page table into page directory - // Set the first entry of the page directory to point to the first_page_table - // Flags: Present (1), Read/Write (1), Kernel-mode (0) - page_directory[0] = ((uint32_t)fpage_table) | 3; - - // Load page directory into CR3 - __asm__ __volatile__("mov %0, %%cr3" :: "r"(&page_directory) : "memory"); + page_table_t* table = page_directory->tables[pd_index]; + table->pages[pt_index].frame = phys >> 12; + table->pages[pt_index].present = 1; + table->pages[pt_index].rw = 1; + table->pages[pt_index].user = 1; +} - // Enable paging by setting bit 31 in CR0 +void switch_page_directory(page_directory_t *dir) { uint32_t cr0; - __asm__ __volatile__("mov %%cr0, %0" : "=r"(cr0)); - cr0 |= 0x80000000; // Set PG bit - __asm__ __volatile__("mov %0, %%cr0" :: "r"(cr0) : "memory"); - - vga_print_string("[OK]\n"); + // Load CR3 with the address of the physical_tables array + asm volatile("mov %0, %%cr3" :: "r"(&dir->physical_tables)); + asm volatile("mov %%cr0, %0" : "=r"(cr0)); + cr0 |= 0x80000000; // Enable paging + asm volatile("mov %0, %%cr0" :: "r"(cr0)); +} +void page_fault_handler(registers_t *r) { + (void)r; + uint32_t faulting_address; + __asm__ __volatile__("mov %%cr2, %0" : "=r" (faulting_address)); + vga_print_string("Page Fault at 0x"); + vga_print_hex(faulting_address); + vga_print_string("\n"); + __asm__ __volatile__("cli"); + for(;;) { __asm__ __volatile__("hlt"); } +} +void paging_install(void) { + page_directory = (page_directory_t*)pmm_alloc_page(); + memset(page_directory, 0, sizeof(page_directory_t)); + for (uint32_t i = 0; i < 0x400000; i += PAGE_SIZE) { + paging_map(i, i, 0x3); + } + for (uint32_t i = 0x00400000; i < 0x01400000; i += PAGE_SIZE) { + paging_map(i, i, 0x3); + } + struct VbeInfoBlock* info = (struct VbeInfoBlock*)0x8000; + uint32_t fb_phys = info->physbase; + + // Safety check: if 0, something is wrong with bootloader, but we try anyway + if (fb_phys != 0) { + // Map 8MB to be safe (covers 1080p easily) + for (uint32_t i = 0; i < 0x00800000; i += PAGE_SIZE) { + paging_map(fb_phys + i, fb_phys + i, 0x3); + } + } + register_interrupt_handler(14, page_fault_handler); + switch_page_directory(page_directory); } \ No newline at end of file diff --git a/paging.h b/paging.h index caa976b..76e91a5 100644 --- a/paging.h +++ b/paging.h @@ -31,11 +31,32 @@ uint32_t paging_get_reserved_end(void); #define PAGING_H #include -typedef uint32_t pt_entry_t; +#include "idt.h" + +// Page Table Entry +typedef struct page { + uint32_t present : 1; // Page present in memory + uint32_t rw : 1; // Read-only if clear, read-write if set + uint32_t user : 1; // Supervisor level only if clear + uint32_t accessed : 1; // Has the page been accessed since last refresh? + uint32_t dirty : 1; // Has the page been written to since last refresh? + uint32_t unused : 7; // Amalgamation of unused and reserved bits + uint32_t frame : 20; // Frame address (shifted right 12 bits) +} page_t; + +typedef struct page_table { + page_t pages[1024]; +} page_table_t; + +typedef struct page_directory { + page_table_t *tables[1024]; // Array of pointers to pagetables. + uint32_t physical_tables[1024]; // Array of physical addresses of pagetables. + uint32_t physicalAddr; // The physical address of physical_tables +} page_directory_t; void paging_install(void); -void map_page(void *physaddr, void *virtualaddr, unsigned int flags); -extern pt_entry_t page_directory[1024]; -extern pt_entry_t first_page_table[1024]; +void paging_map(uint32_t phys, uint32_t virt, uint32_t flags); +void switch_page_directory(page_directory_t *dir); +extern page_directory_t* page_directory; #endif diff --git a/task.c b/task.c index 053517f..9af4774 100644 --- a/task.c +++ b/task.c @@ -3,11 +3,16 @@ #include "vga.h" #include "timer.h" #include "idt.h" -#include - +#include static task_t* current_task; static task_t* ready_queue; static int next_pid = 1; + +void idle_task_func(void){ + while(1){ + __asm__ __volatile__("hlt"); + } +} task_t* get_current_task(void) { return current_task; } @@ -34,75 +39,43 @@ void create_task(char* name, void (*entry_point)(void)) { new_task->id = next_pid++; new_task->state = TASK_READY; - // Allocate one physical page for the kernel stack. - // pmm_alloc_page() returns the base (lowest address) of the page. - // Since the x86 stack grows downward, set the initial stack pointer - // to the *top* of the page by adding PAGE_SIZE. - // Use explicit cast to avoid pointer arithmetic surprises. new_task->kernel_stack = (void*)((uint32_t)pmm_alloc_page() + PAGE_SIZE); uint32_t stack_top = (uint32_t)new_task->kernel_stack; registers_t* initial_regs = (registers_t*)(stack_top - sizeof(registers_t)); memset(initial_regs, 0, sizeof(registers_t)); - initial_regs->eax = 0; - initial_regs->ebx = 0; - initial_regs->ecx = 0; - initial_regs->edx = 0; - initial_regs->esi = 0; - initial_regs->edi = 0; - initial_regs->ebp = 0; initial_regs->eip = (uint32_t)entry_point; - initial_regs->cs = 0x08; - initial_regs->eflags = 0x202; + initial_regs->eflags = 0x202; // Enable interrupts new_task->regs.esp = (uint32_t)initial_regs; - - // Insert into the circular ready queue - if (ready_queue == NULL) { - ready_queue = new_task; - new_task->next = new_task; // Point to itself - } else { - new_task->next = ready_queue->next; - ready_queue->next = new_task; + initial_regs->cs = 0x08; // Kernel code segment + initial_regs->ds = 0x10; // Kernel data segment + // Add to the end of the ready queue + task_t* temp = ready_queue; + while (temp->next != NULL) { + temp = temp->next; } + temp->next = new_task; + new_task->next = ready_queue; __asm__ __volatile__("sti"); } + + void schedule(registers_t* r) { if (!current_task) return; - // Save the state of the current task + // Save the state of the curreint task current_task->regs = *r; - - // If the current task is still running (and not blocked/sleeping), set it to ready - if (current_task->state == TASK_RUNNING) { - current_task->state = TASK_READY; - } - - // Find the next ready task - task_t* next_task = current_task; - do { + task_t* next_task = current_task->next; + while (next_task && next_task->state != TASK_READY) { next_task = next_task->next; - if (next_task->state == TASK_READY) { + if (next_task == current_task) { + // No other ready tasks found + next_task = current_task; break; } - } while (next_task != current_task); - - // If no other task is ready, and current is not ready, we might idle. - // But if we found a ready task (even if it's the current one), we switch. - if (next_task->state != TASK_READY) { - // If current_task is also not ready, we have a problem. - // For now, we just return, which continues the current context. - // In a real scenario, you'd switch to an idle task. - if(current_task->state != TASK_READY) { - current_task->state = TASK_RUNNING; // Prevent getting stuck - } - return; } - - // Switch to the next task current_task = next_task; current_task->state = TASK_RUNNING; - - // Restore the state of the new current task *r = current_task->regs; } diff --git a/task.h b/task.h index 180fbe9..a7e03af 100644 --- a/task.h +++ b/task.h @@ -2,7 +2,7 @@ #define TASK_H #include #include "idt.h" -#include "sync.h" +#include "spinlock.h" typedef enum { TASK_RUNNING, TASK_READY,