From 3c6fd8cb651389de9cc425b6893c5512f9447ed3 Mon Sep 17 00:00:00 2001 From: slinky55 Date: Sun, 12 Jul 2026 03:56:25 -0500 Subject: [PATCH] got some of the pty actually working in userspace --- compile_commands.json | 17 +++++ kernel/drivers/cpio/cpio.c | 37 ++++------- kernel/drivers/devfs/devfs.c | 40 ++++++++++++ kernel/drivers/devfs/devfs.h | 8 +++ kernel/drivers/pty/pty.c | 3 + kernel/drivers/vga/vga.c | 11 ++++ kernel/elf.c | 9 ++- kernel/kmain.c | 21 ++++++- kernel/vfs.c | 15 +++-- kernel/vfs.h | 4 ++ make_img.sh | 12 ++-- programs/lib/rlibc.a | Bin 4408 -> 4408 bytes programs/rocksh/main.c | 2 +- programs/vga_text_term/main.c | 2 +- programs/vga_text_term/syscall.c | 104 ------------------------------- rocklibc/src/syscall.c | 2 +- 16 files changed, 140 insertions(+), 147 deletions(-) create mode 100644 kernel/drivers/devfs/devfs.c create mode 100644 kernel/drivers/devfs/devfs.h delete mode 100644 programs/vga_text_term/syscall.c diff --git a/compile_commands.json b/compile_commands.json index cc99d35..a2afb42 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -67,6 +67,23 @@ "file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c", "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.c.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/devfs/devfs.c.o", + "kernel/drivers/devfs/devfs.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/devfs/devfs.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/devfs/devfs.c.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", diff --git a/kernel/drivers/cpio/cpio.c b/kernel/drivers/cpio/cpio.c index 0e21fe3..53dfbd6 100644 --- a/kernel/drivers/cpio/cpio.c +++ b/kernel/drivers/cpio/cpio.c @@ -2,6 +2,7 @@ #include #include +#include #define MAX_INITRD_FILES 64 @@ -17,9 +18,16 @@ static uint32_t parse_hex_ascii(const char *str, int len) { } static vfs_node_t* cpio_find(vfs_node_t* _dir, const char* name) { + if (strcmp(name, "tvga") == 0) { + kprintf("looking for tvga\n"); + } if (!(_dir->flags & VFS_DIRECTORY)) return NULL; + vfs_node_t* root = _dir; + if (_dir->mnt) { + root = _dir->mnt; + } - vfs_node_t* child = _dir->first_child; + vfs_node_t* child = root->first_child; while (child != NULL) { if (strcmp(child->name, name) == 0) { return child; @@ -39,7 +47,7 @@ static uint32_t cpio_read(struct vfs_node* node, uint32_t offset, uint32_t size, return size; } -static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) { +static vfs_node_t* cpio_find_or_create(vfs_node_t* root_node, const char* path) { vfs_node_t* current = root_node; char path_cpy[256]; @@ -49,8 +57,6 @@ static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) { char* tkn = strtok_r(path_cpy, "/", &sav); while (tkn != NULL) { - char* next_tkn = strtok_r(NULL, "/", &sav); - vfs_node_t* next_node = cpio_find(current, tkn); if (!next_node) { next_node = kalloc(sizeof(vfs_node_t)); @@ -65,7 +71,7 @@ static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) { } current = next_node; - tkn = next_tkn; + tkn = strtok_r(NULL, "/", &sav); } return current; @@ -99,26 +105,7 @@ vfs_node_t* cpio_read_fs(uint32_t _vaddr) { uint8_t* file_data = (uint8_t*)header + file_data_offset; if (strcmp(".", filename) != 0) { - vfs_node_t* parent = cpio_get_or_create(cpio_root, filename); - - char* base_name = filename; - for (int i = strlen(filename) - 1; i >= 0; i--) { - if (filename[i] == '/') { - base_name = &filename[i + 1]; - break; - } - } - - vfs_node_t* current = cpio_find(parent, base_name); - if (!current) { - current = kalloc(sizeof(vfs_node_t)); - memset((void*)current, 0, sizeof(vfs_node_t)); - strcpy(current->name, base_name); - - current->next_sibling = parent->first_child; - parent->first_child = current; - } - + vfs_node_t* current = cpio_find_or_create(cpio_root, filename); if ((mode & 0xF000) == 0x4000) { current->flags = VFS_DIRECTORY; current->find = cpio_find; diff --git a/kernel/drivers/devfs/devfs.c b/kernel/drivers/devfs/devfs.c new file mode 100644 index 0000000..4ee814c --- /dev/null +++ b/kernel/drivers/devfs/devfs.c @@ -0,0 +1,40 @@ +#include "vfs.h" +#include + +#include +#include +#include + +static vfs_node_t* devfs_find(vfs_node_t* parent, const char* name) { + vfs_node_t* cur = parent->first_child; + if (!cur) return NULL; + + while (cur) { + if (strcmp(cur->name, name) == 0) break; + cur = cur->next_sibling; + } + + return cur; +} + +static vfs_node_t* devfs_create(vfs_node_t* parent, const char* name) { + vfs_node_t* node = kalloc(sizeof(vfs_node_t*)); + memset((void*)node, 0, sizeof(vfs_node_t)); + strcpy(node->name, name); + node->flags = VFS_CHARDEVICE; + if (parent->first_child) { + node->next_sibling = parent->first_child; + } + parent->first_child = node; + return node; +} + +vfs_node_t* create_devfs() { + vfs_node_t* root = kalloc(sizeof(vfs_node_t*)); + memset((void*)root, 0, sizeof(vfs_node_t)); + strcpy(root->name, "dev"); + root->find = devfs_find; + root->flags = VFS_DIRECTORY; + root->create = devfs_create; + return root; +} \ No newline at end of file diff --git a/kernel/drivers/devfs/devfs.h b/kernel/drivers/devfs/devfs.h new file mode 100644 index 0000000..1d03d11 --- /dev/null +++ b/kernel/drivers/devfs/devfs.h @@ -0,0 +1,8 @@ +#ifndef D_DEVFS_H +#define D_DEVFS_H + +#include + +vfs_node_t* create_devfs(); + +#endif \ No newline at end of file diff --git a/kernel/drivers/pty/pty.c b/kernel/drivers/pty/pty.c index a1b3a2c..cc9e8d3 100644 --- a/kernel/drivers/pty/pty.c +++ b/kernel/drivers/pty/pty.c @@ -1,6 +1,9 @@ #include "lib/ringbuf.h" + #include +#include + uint32_t pty_master_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) { pty_t* pty = (pty_t*)node->data; uint32_t bytes_read = 0; diff --git a/kernel/drivers/vga/vga.c b/kernel/drivers/vga/vga.c index 8c90b01..ea1f930 100644 --- a/kernel/drivers/vga/vga.c +++ b/kernel/drivers/vga/vga.c @@ -77,4 +77,15 @@ void vga_putchar(char c) { if (++terminal_row == VGA_HEIGHT) terminal_row = 0; } +} + +uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) { + terminal_row = offset / VGA_WIDTH; + terminal_column = offset % VGA_WIDTH; + + for (uint32_t i = 0; i < size; i++) { + vga_putchar((char)buf[i]); + } + + return size; } \ No newline at end of file diff --git a/kernel/elf.c b/kernel/elf.c index 1048b2b..50f3ece 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -1,13 +1,16 @@ #include "elf.h" #include "vfs.h" #include "memory/mm.h" +#include "process.h" +#include "scheduler.h" #include +#include uint32_t load_elf_program(const char* prgm) { int fd = vfs_open(prgm, 0); if (fd == -1) { - return -1; + return 0; } elf_header_t* e_hdr = kalloc(sizeof(elf_header_t)); @@ -15,12 +18,12 @@ uint32_t load_elf_program(const char* prgm) { uint32_t bytes_rd = vfs_read(fd, e_hdr, sizeof(elf_header_t)); if (bytes_rd <= 0) { - return -1; + return 0; } uint32_t ph_table_ptr = e_hdr->e_phoff; elf_program_header_t* ph = kalloc(sizeof(elf_program_header_t)); - uint32_t heap_start = 0; + uint32_t heap_start = 0; for (uint32_t i = 0; i < e_hdr->e_phnum; i++) { vfs_seek(fd, ph_table_ptr); diff --git a/kernel/kmain.c b/kernel/kmain.c index 8dca6c2..f5d320f 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,10 @@ void load_root_program(const char* path) { flush_tlb(); uint32_t eip = load_elf_program(path); + if (eip == 0) { + kprintf("Failed to load elf program file\n"); + return; + } uint32_t stack_sz = PAGE_SIZE * 16; uint32_t stack_top = 0xBFFF0000; @@ -122,12 +127,26 @@ void kmain(uint32_t magic, multiboot_info* mbi) { vfs_mount(vfs_root, initrd_root); kprintf("initrd read, mounted @ /\n"); + vfs_node_t* devfs = create_devfs(); + if (!devfs) { + kprintf("failed to create devfs\n"); + return; + } + + vfs_node_t* vga_dev = devfs->create(devfs, "tvga"); + vga_dev->write = vga_write; + + vfs_node_t* dev = vfs_find("/dev"); + if (dev) { + dev->mnt = devfs; + } + disable_interrupts(); init_scheduler(); enable_interrupts(); kprintf("loading terminal program\n"); - load_root_program("/vga_text_term.elf"); + load_root_program("/bin/vga_text_term.elf"); kprintf("kernel going to sleep...\n"); } diff --git a/kernel/vfs.c b/kernel/vfs.c index 559de67..40e6a56 100644 --- a/kernel/vfs.c +++ b/kernel/vfs.c @@ -28,9 +28,11 @@ void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs) { vfs_node_t* vfs_find(const char* path) { vfs_node_t* current = root; + if (current->mnt) { + current = current->mnt; + } char* sav = NULL; - size_t path_sz = strlen(path) + 1; char* path_cpy = kalloc(path_sz); memset((uint8_t*)path_cpy, 0, path_sz); @@ -38,24 +40,27 @@ vfs_node_t* vfs_find(const char* path) { char* tkn = strtok_r(path_cpy, "/", &sav); while (tkn != NULL) { + if (current && current->mnt) { + current = current->mnt; + } + if (!current || !current->find) { return NULL; } - + current = current->find(current, tkn); - tkn = strtok_r(NULL, "/", &sav); if (current == NULL) { return NULL; } + tkn = strtok_r(NULL, "/", &sav); if (tkn && !(current->flags & VFS_DIRECTORY)) { return NULL; } } - - kfree(path_cpy); + kfree(path_cpy); return current; } diff --git a/kernel/vfs.h b/kernel/vfs.h index 3eb9dc9..281d87a 100644 --- a/kernel/vfs.h +++ b/kernel/vfs.h @@ -16,6 +16,7 @@ typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer); typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name); typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name); +typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name); typedef struct vfs_node { char name[128]; @@ -29,6 +30,7 @@ typedef struct vfs_node { write_type_t write; finddir_type_t find; mkdir_type_t mkdir; + create_type_t create; struct vfs_node* mnt; void* data; @@ -43,6 +45,8 @@ typedef struct { vfs_node_t* vfs_create_root(); vfs_node_t* vfs_mkdir(vfs_node_t* parent, const char* name); +vfs_node_t* vfs_find(const char* path); + void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs); int vfs_open(const char* path, int flags); int vfs_read(int fd, void* buf, size_t sz); diff --git a/make_img.sh b/make_img.sh index d2b854a..8a211b2 100755 --- a/make_img.sh +++ b/make_img.sh @@ -1,14 +1,14 @@ #!/bin/bash mkdir -p initrd -rm -f initrd/*.elf +rm -f initrd/bin/*.elf -cp programs/bin/* initrd +mkdir -p initrd/dev +mkdir -p initrd/bin +cp programs/bin/* initrd/bin cd initrd -mkdir -p dev -mkdir -p output -find . -depth -print | cpio -o -H newc > output/initrd.img +find . -depth -print | cpio -o -H newc > ../initrd.img cd .. -cp initrd/output/*.img isodir/boot \ No newline at end of file +cp initrd.img isodir/boot \ No newline at end of file diff --git a/programs/lib/rlibc.a b/programs/lib/rlibc.a index a9203f79901570be461327d8971e781053f3d433..4f9063b3ad4ebf7c8ee0937e28098f571cb7111e 100644 GIT binary patch delta 99 zcmdm?v_olv44Z|CnTeUndvYCXvAp4>9jput44oG{p9Xiwa-41G mj{S4;uwL&LHJ~WNgv|nMDvXTcn@!oRnPA%Zfc#$0)$9P@vK?*! delta 99 zcmdm?v_olv44avyk%_taM5Sj?)@DA&EEXtxavf{2{0>$I28Pb3!QHVOXB)a>|C~Im m*SkdxD8``ITcXCWS%6K2kx_WFDZ4cjOdB7g_~u^D)$9PIb{p*g diff --git a/programs/rocksh/main.c b/programs/rocksh/main.c index 7e5d1ea..6283e46 100644 --- a/programs/rocksh/main.c +++ b/programs/rocksh/main.c @@ -9,5 +9,5 @@ int main(int argc, char *argv[]) { printf(shell_prompt); - return 3; + return 0; } \ No newline at end of file diff --git a/programs/vga_text_term/main.c b/programs/vga_text_term/main.c index 29917ac..6d2fa2f 100644 --- a/programs/vga_text_term/main.c +++ b/programs/vga_text_term/main.c @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) { dup2(0, 1); dup2(0, 2); - exec("/rocksh.elf"); + exec("/bin/rocksh.elf"); } close(ptys); diff --git a/programs/vga_text_term/syscall.c b/programs/vga_text_term/syscall.c deleted file mode 100644 index b50d52f..0000000 --- a/programs/vga_text_term/syscall.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include - -#include "memory/mm.h" -#include "process.h" -#include "scheduler.h" -#include "kbd.h" - -#include - -#include - - -static int32_t sys_exit(int status) { - process_t* task = current_task(); - task->state = STATE_DEAD; - kprintf("Process %d exited with status %d\n", task->pid, status); - exit(); - return 0; -} - -static int32_t sys_write(int fd, const void* buf, size_t count) { - if (fd == 1 || fd == 2) { // stdout or stderr - const char* cbuf = (const char*)buf; - for (size_t i = 0; i < count; i++) { - vga_putchar(cbuf[i]); - } - return count; - } - return -1; -} - -static int32_t sys_read(int fd, void* buf, size_t count) { - if (fd == 0) { - char* cbuf = (char*)buf; - size_t bytes_read = 0; - - while (bytes_read < count) { - kbd_wait(); - - if (kbd_ready()) { - char c = kbd_read(); - cbuf[bytes_read++] = c; - if (c == '\n') break; - } - } - return bytes_read; - } - return -1; -} - -static int32_t sys_open(const char* filename, int flags) { - return -1; -} - -static int32_t sys_close(int fd) { - return -1; -} - -static int32_t sys_brk(uint32_t new_break) { - process_t* current = current_task(); - - if (new_break == 0) { - return current->heap_end; - } - - if (new_break < current->heap_end) { - current->heap_end = new_break; - return current->heap_end; - } - - uint32_t page_start = (current->heap_end + 4095) & ~4095; - uint32_t page_end = (new_break + 4095) & ~4095; - - for (uint32_t addr = page_start; addr < page_end; addr += 4096) { - // 1. Allocate a physical frame using your PMM (Physical Memory Manager) - void* phys = p_alloc_frame(); - - // 2. Map it into the current page directory using your VMM (Virtual Memory Manager) - map_page(addr, (uint32_t)phys, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER); - } - - current->heap_end = new_break; - return current->heap_end; -} - -typedef struct registers { - uint32_t gs, fs, es, ds; // Pushed manually - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha - uint32_t int_no, err_code; // Pushed manually - uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU -} registers_t; -int32_t syscall(registers_t* regs) { - switch(regs->eax) { - case 1: return sys_exit(regs->ebx); - case 3: return sys_read(regs->ebx, (void*)regs->ecx, regs->edx); - case 4: return sys_write(regs->ebx, (const void*)regs->ecx, regs->edx); - case 5: return sys_open((const char*)regs->ebx, regs->ecx); - case 6: return sys_close(regs->ebx); - case 12: return sys_brk(regs->ebx); - default: - return -1; - } -} \ No newline at end of file diff --git a/rocklibc/src/syscall.c b/rocklibc/src/syscall.c index af9814c..486a55b 100644 --- a/rocklibc/src/syscall.c +++ b/rocklibc/src/syscall.c @@ -28,7 +28,7 @@ void exit(int status) { } int open(const char* path) { - return syscall1(SYS_OPEN, (uint32_t)path); + return syscall3(SYS_OPEN, (uint32_t)path, 0, 0); } int write(int fd, const void* buf, size_t cnt) {