From b6681b74c964ce968f57b0f4210a970bbaa3b44a Mon Sep 17 00:00:00 2001 From: slinky55 Date: Thu, 16 Jul 2026 23:19:54 -0500 Subject: [PATCH] vga now working with term and shell program --- build_programs.sh | 2 +- kernel/drivers/vga/vga.c | 4 +- kernel/kmain.c | 9 +- kernel/lib/print.c | 1 - kernel/memory/mm.c | 2 +- kernel/memory/mm.h | 1 + kernel/scheduler.c | 9 +- kernel/syscall.c | 15 +-- programs/rocksh/main.c | 4 +- programs/rockterm/main.c | 201 +++++++++++++++++++++++++++++++++------ rlibc/include/stdlib.h | 1 + rlibgui/rlibgui.a | Bin 616 -> 616 bytes 12 files changed, 196 insertions(+), 53 deletions(-) diff --git a/build_programs.sh b/build_programs.sh index a2fcfc7..7857e9d 100755 --- a/build_programs.sh +++ b/build_programs.sh @@ -13,4 +13,4 @@ find "." -type f \( -name "Makefile" -o -name "makefile" \) | while read -r make ) done -cd.. \ No newline at end of file +cd .. \ No newline at end of file diff --git a/kernel/drivers/vga/vga.c b/kernel/drivers/vga/vga.c index 8955782..e521c15 100644 --- a/kernel/drivers/vga/vga.c +++ b/kernel/drivers/vga/vga.c @@ -30,7 +30,7 @@ uint32_t vga_mmap(vfs_node_t* node, uint32_t address) { for (uint32_t i = 0; i < num_pages; i++) { uint32_t phys_addr = framebuffer_address + (i * 4096); uint32_t virt_addr = address + (i * 4096); - map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE); + map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER | PAGE_MMIO); } return address; } @@ -70,7 +70,7 @@ void vga_init( for (uint32_t i = 0; i < num_pages; i++) { uint32_t phys_addr = fb_paddr + (i * 4096); uint32_t virt_addr = VGA_FRAMEBUFFER + (i * 4096); - map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE); + map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE | PAGE_MMIO); } vga_clear_scrn(0x00000000); diff --git a/kernel/kmain.c b/kernel/kmain.c index 1973c8c..e1d9e38 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -166,14 +166,7 @@ void kmain(multiboot_info* mbi) { dev->mnt = devfs; kprintf("mounted devfs\n"); - int font_loaded = set_console_font("/usr/fonts/kernel_font.psf"); - if (!font_loaded) { - kprintf("failed to load console font\n"); - } - console_init(); - - kprintf("kernel console initialized\n"); - kprintf("basic initializations complete. check serial for details\n"); + kprintf("basic initializations complete\n"); kprintf("starting rockos\n"); load_root_program("/usr/bin/rockterm"); diff --git a/kernel/lib/print.c b/kernel/lib/print.c index 4be6dce..2ea859f 100644 --- a/kernel/lib/print.c +++ b/kernel/lib/print.c @@ -16,7 +16,6 @@ static char* hex_chars = "0123456789abcdef"; static void kwrite(char c) { write_serial(c); - console_putchar(c); } static void kprint(const char *str) { diff --git a/kernel/memory/mm.c b/kernel/memory/mm.c index 973821b..58f7345 100644 --- a/kernel/memory/mm.c +++ b/kernel/memory/mm.c @@ -247,7 +247,7 @@ void* clone_current_pd() { uint32_t pte_src = pt_src[j]; if (!(pte_src & PAGE_PRESENT)) continue; - if (!(pte_src & PAGE_WRITABLE)) { + if (!(pte_src & PAGE_WRITABLE) || (pte_src & PAGE_MMIO)) { pt_dst[j] = pt_src[j]; continue; } diff --git a/kernel/memory/mm.h b/kernel/memory/mm.h index 0877456..928bbd0 100644 --- a/kernel/memory/mm.h +++ b/kernel/memory/mm.h @@ -7,6 +7,7 @@ #define PAGE_WRITABLE (1 << 1) #define PAGE_USER (1 << 2) #define PAGE_COW (1 << 9) +#define PAGE_MMIO (1 << 10) #define TEMP_KERNPD_VADDR 0xDFF90000 #define TEMP_TASKPD_VADDR 0xDFFA0000 diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 25bde99..b83ca16 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -25,7 +25,14 @@ void unlock_scheduler() { enable_interrupts(); } +typedef struct registers { + uint32_t ds; // push %ds + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushal + uint32_t eip, cs, eflags, useresp, ss; // pushed by cpu +} __attribute__((packed)) registers_t; + uint32_t switch_context(uint32_t current_esp) { + registers_t* regs = (registers_t*)current_esp; current_process->esp = current_esp; process_t* next_process = current_process->sched_next; @@ -62,8 +69,6 @@ uint32_t switch_context(uint32_t current_esp) { if (current_process->flags & PROCESS_FLAG_USER) { tss.esp0 = current_process->kstack_top; } - - return current_process->esp; } diff --git a/kernel/syscall.c b/kernel/syscall.c index 4804e8c..a0771cc 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1,6 +1,7 @@ #include #include +#include "drivers/serial/serial.h" #include "lib/memory.h" #include "lib/ringbuf.h" @@ -25,11 +26,12 @@ typedef struct registers { static int32_t sys_exit(int status) { process_t* task = current_task(); - task->state = STATE_ZOMBIE; - task->exit_status = status; - if (task->waiting) { - wake(task->waiting); - } + task->state = STATE_DEAD; + // task->exit_status = status; + // if (task->waiting) { + // wake(task->waiting); + // } + kprintf("task %d exited with status %d\n", task->pid, status); exit(); return 0; } @@ -212,6 +214,7 @@ static int32_t sys_exec(registers_t* regs, const char* prgm) { regs->eip = eip; regs->useresp = (uint32_t)u_esp; + print_serial("returning from exec\n"); return 0; } @@ -253,7 +256,7 @@ static int32_t sys_mmap(int fd) { if (!(file->node->flags & VFS_CHARDEVICE)) return 0; - uint32_t map_vaddr = 0x3FF00000; + uint32_t map_vaddr = 0x20000000; return file->node->mmap(file->node, map_vaddr); } diff --git a/programs/rocksh/main.c b/programs/rocksh/main.c index 201dc16..0791b7d 100644 --- a/programs/rocksh/main.c +++ b/programs/rocksh/main.c @@ -1,7 +1,7 @@ #include "syscall.h" #include #include -#include +#include #include const char* shell_prompt = "rocksh> "; @@ -11,7 +11,7 @@ size_t buf_offset = 0; char path[256]; -const char* bin_dir = "/bin/"; +const char* bin_dir = "/usr/bin/"; void parse_cmd() { if (strcmp(buf, "exit") == 0) { diff --git a/programs/rockterm/main.c b/programs/rockterm/main.c index 59ac5e2..2bc1850 100644 --- a/programs/rockterm/main.c +++ b/programs/rockterm/main.c @@ -1,74 +1,215 @@ #include +#include +#include +#include #include typedef struct { + uint8_t magic[2]; + uint8_t mode; + uint8_t charsz; +} psf_hdr_t; -} font_t; +typedef struct { + int fd; + psf_hdr_t hdr; + void* glyphs; +} psf_font_t; + +psf_font_t* load_font(const char* path); +void free_font(psf_font_t* font); void term_write_char(char c); -void render_char_at(char c, int x, int y); +void render_char(char c); +void clear(uint32_t color); +void spawn_shell(); -int spawn_shell(); +void start_terminal(); -int ptys; -int ptym; +static int ptys; +static int ptym; +static int vga_fd; -void* fb; -fb_info_t fb_info; +static void* fb = NULL; +static fb_info_t fb_info; -int terminal_col = 0; -int terminal_row = 0; +static uint32_t console_row = 0; +static uint32_t console_col = 0; +static uint32_t console_width = 0; +static uint32_t console_height = 0; +static uint32_t console_text_color = 0; +static uint32_t console_backgrnd_color = 0; -font_t* terminal_font = NULL; +static int shell_pid; + +psf_font_t* terminal_font = NULL; int main(int argc, char *argv[]) { (void)argc; (void)argv; - int vga_fd = open("/dev/vga"); - if (vga_fd == -1) return 1; + ptym = pty(&ptys); - int kbd_fd = open("/dev/kbd"); - if (kbd_fd == -1) return 1; + vga_fd = open("/dev/vga"); + if (vga_fd == -1) return 1; int res = ioctl(vga_fd, FBIOGET_INFO, &fb_info); if (!res) { return 1; } - mmap(vga_fd); + fb = mmap(vga_fd); - // if (!spawn_shell()) { - // return 1; - // } + terminal_font = load_font("/usr/fonts/kernel_font.psf"); + if (!terminal_font) { + return 1; + } + + console_height = fb_info.height / terminal_font->hdr.charsz; + console_width = fb_info.width / 8; + console_text_color = 0xFFFFFFFF; + console_backgrnd_color = 0xFF6c7482; + + start_terminal(); + + free_font(terminal_font); + close(vga_fd); + close(ptym); return 0; } -void render_char_at(char c, int x, int y) { +void render_char(char c) { if (!terminal_font) return; + uint32_t vga_pitch = fb_info.pitch; + uint8_t* glyph = (uint8_t*)terminal_font->glyphs + (c * terminal_font->hdr.charsz); + + uint32_t pixel_y_start = console_row * terminal_font->hdr.charsz; + uint32_t pixel_x_start = console_col * 8; + + for (uint32_t y = 0; y < terminal_font->hdr.charsz; y++) { + uint8_t bits = glyph[y]; + uint8_t* row_bytes = (uint8_t*)fb + ((pixel_y_start + y) * vga_pitch); + uint32_t* pixel_row = (uint32_t*)row_bytes; + + for (int x = 0; x < 8; x++) { + if (bits & (0b10000000 >> x)) { + pixel_row[pixel_x_start + x] = console_text_color; + } else { + pixel_row[pixel_x_start + x] = console_backgrnd_color; + } + } + } } -void term_write_char(char c) { - -} - -int spawn_shell() { - ptym = pty(&ptys); - - if (fork() == 0) { +void spawn_shell() { + if ((shell_pid = fork()) == 0) { close(ptym); + close(vga_fd); + dup2(ptys, 0); dup2(0, 1); dup2(0, 2); - - if (!exec("/usr/bin/rocksh")) return 0; + if (!exec("/usr/bin/rocksh")) exit(1); } close(ptys); dup2(ptym, 0); dup2(0, 1); dup2(0, 2); - return 1; +} + +void clear(uint32_t color) { + for (uint32_t i = 0; i < fb_info.fb_size; i++) { + ((uint32_t*)fb)[i] = color; + } +} + +psf_font_t* load_font(const char* path) { + int fd = open(path); + if (fd == -1) { + return NULL; + } + + psf_hdr_t header; + int rd = read(fd, &header, sizeof(psf_hdr_t)); + if (rd <= 0) { + return NULL; + } + + uint32_t num_glyphs = (header.mode & (1 << 0)) ? 512 : 256; + uint32_t glyph_sz = header.charsz; + size_t glyph_buf_sz = num_glyphs * glyph_sz; + + void* glyphs = malloc(glyph_buf_sz); + + rd = 0; + rd = read(fd, glyphs, glyph_buf_sz); + if (rd <= 0) { + free(glyphs); + return NULL; + } + + psf_font_t* font = (psf_font_t*)malloc(sizeof(psf_font_t)); + font->fd = fd; + font->hdr = header; + font->glyphs = glyphs; + return font; +} + +void free_font(psf_font_t* font) { + close(font->fd); + free(font->glyphs); + free(font); +} + +void term_write_char(char c) { + if (!terminal_font) return; + + if (c == '\n') { + console_col = 0; + console_row++; + if (console_row >= console_height) { + console_row = 0; + } + return; + } + + render_char(c); + + console_col++; + if (console_col >= console_width) { + console_col = 0; + console_row++; + } + + if (console_row >= console_height) { + console_row = 0; + } +} + +void start_terminal() { + spawn_shell(); + + clear(console_backgrnd_color); + + int kbd_fd = open("/dev/kbd"); + if (kbd_fd == -1) return; + + while (1) { + char c; + int rd = read(STDIN_FILENO, &c, 1); + if (rd > 0) { + term_write_char(c); + continue; + } + + rd = 0; + c = 0; + rd = read(kbd_fd, &c, 1); + if (rd > 0) { + write(STDOUT_FILENO, &c, 1); + } + } } \ No newline at end of file diff --git a/rlibc/include/stdlib.h b/rlibc/include/stdlib.h index a6ebd4a..f9ff8f6 100644 --- a/rlibc/include/stdlib.h +++ b/rlibc/include/stdlib.h @@ -4,5 +4,6 @@ #include void* malloc(size_t size); +void free(void* ptr); #endif \ No newline at end of file diff --git a/rlibgui/rlibgui.a b/rlibgui/rlibgui.a index 11195e70b97f3c58924adc5f31a1da1859a77628..cd7d8c17ad3324ce9f7f029127979ecb02baa440 100644 GIT binary patch delta 25 ccmaFC@`7c8EUTHJrHREvC2I&{V-gz^0Ag|mu>b%7 delta 25 ccmaFC@`7c8EUU4Zp@G>%C2I&{V-gz^0AXwfnE(I)