From 454de8feed8e1ff633dd40a31317d4500f4b1221 Mon Sep 17 00:00:00 2001 From: slinky55 Date: Tue, 14 Jul 2026 00:07:50 -0500 Subject: [PATCH] trying to get VGA fb mode to work.. --- compile_commands.json | 462 ++++++++++++++++----------------- kernel/boot/boot.S | 24 +- kernel/drivers/vga/vga.c | 83 +++--- kernel/drivers/vga/vga.h | 10 +- kernel/kmain.c | 17 +- kernel/multiboot.h | 23 ++ kernel/syscall.c | 20 ++ programs/lib/rlibc.a | Bin 4542 -> 7276 bytes programs/rocksh/main.c | 11 +- rocklibc/compile_commands.json | 51 ++++ rocklibc/include/stdlib.h | 8 + rocklibc/include/string.h | 1 + rocklibc/include/syscall.h | 4 +- rocklibc/src/malloc.c | 74 ++++++ rocklibc/src/strcat.c | 8 + rocklibc/src/strtok.c | 63 +++++ rocklibc/src/syscall.c | 8 + 17 files changed, 567 insertions(+), 300 deletions(-) create mode 100644 rocklibc/include/stdlib.h create mode 100644 rocklibc/src/malloc.c create mode 100644 rocklibc/src/strcat.c create mode 100644 rocklibc/src/strtok.c diff --git a/compile_commands.json b/compile_commands.json index 3e32c19..a2afb42 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -26,12 +26,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/kbd.c.o", - "kernel/kbd.c" + "obj/kernel/vfs.c.o", + "kernel/vfs.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/kbd.c", - "output": "/home/slinky/source/RockOS/obj/kernel/kbd.c.o" + "file": "/home/slinky/source/RockOS/kernel/vfs.c", + "output": "/home/slinky/source/RockOS/obj/kernel/vfs.c.o" }, { "arguments": [ @@ -43,12 +43,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/gdt.c.o", - "kernel/gdt.c" + "obj/kernel/kmain.c.o", + "kernel/kmain.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/gdt.c", - "output": "/home/slinky/source/RockOS/obj/kernel/gdt.c.o" + "file": "/home/slinky/source/RockOS/kernel/kmain.c", + "output": "/home/slinky/source/RockOS/obj/kernel/kmain.c.o" }, { "arguments": [ @@ -67,6 +67,91 @@ "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", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/cpio/cpio.c.o", + "kernel/drivers/cpio/cpio.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/cpio/cpio.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/cpio/cpio.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/pty/pty.c.o", + "kernel/drivers/pty/pty.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/pty/pty.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pty/pty.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/vga/vga.c.o", + "kernel/drivers/vga/vga.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/ide/ide.c.o", + "kernel/drivers/ide/ide.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/ide/ide.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ide/ide.c.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -111,12 +196,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/drivers/ide/ide.c.o", - "kernel/drivers/ide/ide.c" + "obj/kernel/gdt.c.o", + "kernel/gdt.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/ide/ide.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ide/ide.c.o" + "file": "/home/slinky/source/RockOS/kernel/gdt.c", + "output": "/home/slinky/source/RockOS/obj/kernel/gdt.c.o" }, { "arguments": [ @@ -128,12 +213,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/drivers/vga/vga.c.o", - "kernel/drivers/vga/vga.c" + "obj/kernel/memory/mm.c.o", + "kernel/memory/mm.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga.c.o" + "file": "/home/slinky/source/RockOS/kernel/memory/mm.c", + "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.c.o" }, { "arguments": [ @@ -145,80 +230,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/drivers/cpio/cpio.c.o", - "kernel/drivers/cpio/cpio.c" + "obj/kernel/kbd.c.o", + "kernel/kbd.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/cpio/cpio.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/cpio/cpio.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", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/pty/pty.c.o", - "kernel/drivers/pty/pty.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/pty/pty.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pty/pty.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/scheduler.c.o", - "kernel/scheduler.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/scheduler.c", - "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/elf.c.o", - "kernel/elf.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/elf.c", - "output": "/home/slinky/source/RockOS/obj/kernel/elf.c.o" + "file": "/home/slinky/source/RockOS/kernel/kbd.c", + "output": "/home/slinky/source/RockOS/obj/kernel/kbd.c.o" }, { "arguments": [ @@ -254,6 +271,23 @@ "file": "/home/slinky/source/RockOS/kernel/interrupts.c", "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.c.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/elf.c.o", + "kernel/elf.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/elf.c", + "output": "/home/slinky/source/RockOS/obj/kernel/elf.c.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -271,57 +305,6 @@ "file": "/home/slinky/source/RockOS/kernel/syscall.c", "output": "/home/slinky/source/RockOS/obj/kernel/syscall.c.o" }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/kmain.c.o", - "kernel/kmain.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/kmain.c", - "output": "/home/slinky/source/RockOS/obj/kernel/kmain.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/lib/tasks.c.o", - "kernel/lib/tasks.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/tasks.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/tasks.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/lib/ringbuf.c.o", - "kernel/lib/ringbuf.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/ringbuf.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/ringbuf.c.o" - }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -349,12 +332,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/lib/strtok.c.o", - "kernel/lib/strtok.c" + "obj/kernel/lib/memory.c.o", + "kernel/lib/memory.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/strtok.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/strtok.c.o" + "file": "/home/slinky/source/RockOS/kernel/lib/memory.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/memory.c.o" }, { "arguments": [ @@ -383,12 +366,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/lib/memory.c.o", - "kernel/lib/memory.c" + "obj/kernel/lib/ringbuf.c.o", + "kernel/lib/ringbuf.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/memory.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/memory.c.o" + "file": "/home/slinky/source/RockOS/kernel/lib/ringbuf.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/ringbuf.c.o" }, { "arguments": [ @@ -400,12 +383,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/vfs.c.o", - "kernel/vfs.c" + "obj/kernel/lib/tasks.c.o", + "kernel/lib/tasks.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/vfs.c", - "output": "/home/slinky/source/RockOS/obj/kernel/vfs.c.o" + "file": "/home/slinky/source/RockOS/kernel/lib/tasks.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/tasks.c.o" }, { "arguments": [ @@ -417,12 +400,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/memory/mm.c.o", - "kernel/memory/mm.c" + "obj/kernel/lib/strtok.c.o", + "kernel/lib/strtok.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/memory/mm.c", - "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.c.o" + "file": "/home/slinky/source/RockOS/kernel/lib/strtok.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/strtok.c.o" }, { "arguments": [ @@ -434,46 +417,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/drivers/pic/pic.S.o", - "kernel/drivers/pic/pic.S" + "obj/kernel/scheduler.c.o", + "kernel/scheduler.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.S", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.S.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/ps2/ps2.S.o", - "kernel/drivers/ps2/ps2.S" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2.S", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2.S.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/pit/pit.S.o", - "kernel/drivers/pit/pit.S" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o" + "file": "/home/slinky/source/RockOS/kernel/scheduler.c", + "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.c.o" }, { "arguments": [ @@ -492,40 +441,6 @@ "file": "/home/slinky/source/RockOS/kernel/syscall.S", "output": "/home/slinky/source/RockOS/obj/kernel/syscall.S.o" }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/interrupts.S.o", - "kernel/interrupts.S" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/interrupts.S", - "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.S.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/boot/boot.S.o", - "kernel/boot/boot.S" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/boot/boot.S", - "output": "/home/slinky/source/RockOS/obj/kernel/boot/boot.S.o" - }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -553,12 +468,46 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/scheduler.S.o", - "kernel/scheduler.S" + "obj/kernel/drivers/pic/pic.S.o", + "kernel/drivers/pic/pic.S" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/scheduler.S", - "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.S.o" + "file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.S", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/pit/pit.S.o", + "kernel/drivers/pit/pit.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/ps2/ps2.S.o", + "kernel/drivers/ps2/ps2.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2.S", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2.S.o" }, { "arguments": [ @@ -577,6 +526,40 @@ "file": "/home/slinky/source/RockOS/kernel/memory/mm.S", "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.S.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/boot/boot.S.o", + "kernel/boot/boot.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/boot/boot.S", + "output": "/home/slinky/source/RockOS/obj/kernel/boot/boot.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/scheduler.S.o", + "kernel/scheduler.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/scheduler.S", + "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.S.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -593,5 +576,22 @@ "directory": "/home/slinky/source/RockOS", "file": "/home/slinky/source/RockOS/kernel/gdt.S", "output": "/home/slinky/source/RockOS/obj/kernel/gdt.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/interrupts.S.o", + "kernel/interrupts.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/interrupts.S", + "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.S.o" } ] diff --git a/kernel/boot/boot.S b/kernel/boot/boot.S index 73f7ada..6f3f607 100644 --- a/kernel/boot/boot.S +++ b/kernel/boot/boot.S @@ -1,14 +1,26 @@ .set ALIGN, 1<<0 /* align loaded modules on page boundaries */ .set MEMINFO, 1<<1 /* provide memory map */ -.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */ +.set GRAPHICS, 1<<2 /* <-- NEW: Request video mode table/framebuffer from GRUB */ +.set FLAGS, ALIGN | MEMINFO | GRAPHICS /* Updated to include GRAPHICS */ .set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ -.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ +.set CHECKSUM, -(MAGIC + FLAGS) /* recalculated checksum of the new flags */ .section .multiboot, "a" -.align 4 -.long MAGIC -.long FLAGS -.long CHECKSUM + .align 4 + .long MAGIC + .long FLAGS + .long CHECKSUM + + .long 0 /* header_addr */ + .long 0 /* load_addr */ + .long 0 /* load_end_addr */ + .long 0 /* bss_end_addr */ + .long 0 /* entry_addr */ + + .long 0 /* Mode Type: 0 = Linear Framebuffer, 1 = Standard EGA Text */ + .long 1024 /* Width (Pixels) */ + .long 768 /* Height (Pixels) */ + .long 32 /* Color Depth (Bits Per Pixel) */ .section .text .global _start diff --git a/kernel/drivers/vga/vga.c b/kernel/drivers/vga/vga.c index 7190898..5e8d589 100644 --- a/kernel/drivers/vga/vga.c +++ b/kernel/drivers/vga/vga.c @@ -7,9 +7,12 @@ #include -#define VGA_WIDTH 80 -#define VGA_HEIGHT 25 -#define VGA_MEMORY (0xB8000 + 0xC0000000) +static uint32_t framebuffer_address; +static uint32_t framebuffer_width; +static uint32_t framebuffer_height; +static uint32_t framebuffer_total_pixels; +static uint32_t framebuffer_pitch; +static uint32_t framebuffer_bpp; enum vga_color { VGA_COLOR_BLACK = 0, @@ -30,52 +33,39 @@ enum vga_color { VGA_COLOR_WHITE = 15, }; -static size_t terminal_row; -static size_t terminal_column; -static uint8_t terminal_color; -static uint16_t* terminal_buffer = (uint16_t*)VGA_MEMORY; +void vga_init( + uint32_t fb_vaddr, + uint32_t fb_width, + uint32_t fb_height, + uint32_t fb_pitch, + uint8_t fb_bpp +) { + framebuffer_address = fb_vaddr; + framebuffer_width = fb_width; + framebuffer_height = fb_height; + framebuffer_pitch = fb_pitch; + framebuffer_bpp = fb_bpp; -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) -{ - return fg | bg << 4; + framebuffer_total_pixels = framebuffer_width * framebuffer_height; + + vga_clear_scrn(0xFFFFFFFF); } -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) -{ - return (uint16_t) uc | (uint16_t) color << 8; -} +void vga_clear_scrn(uint32_t color) { + if (framebuffer_address == 0) return; -static void update_cursor() -{ - uint16_t pos = terminal_row * VGA_WIDTH + terminal_column; - outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t) (pos & 0xFF)); - outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); -} - -void vga_init() { - outb(0x3D4, 0x0A); - outb(0x3D5, (inb(0x3D5) & 0xC0) | 14); - outb(0x3D4, 0x0B); - outb(0x3D5, (inb(0x3D5) & 0xE0) | 15); - - terminal_row = 0; - terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); - } - } + // Completely ignore the framebuffer address for a split second. + // Let's force raw ASCII text into the legacy VGA text console area. + uint16_t* text_mode_buffer = (uint16_t*)0xB8000; + + // Fill the screen with 'A' characters on a red background + for (int i = 0; i < 80 * 25; i++) { + text_mode_buffer[i] = (0x4F << 8) | 'A'; + } } void vga_putchar(char c) { if (c == '\n') { - terminal_row++; - terminal_column = 0; return; } @@ -85,19 +75,9 @@ void vga_putchar(char c) { } return; } - - const size_t index = terminal_row * VGA_WIDTH + terminal_column; - terminal_buffer[index] = vga_entry(c, terminal_color); - if (++terminal_column == VGA_WIDTH) { - terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) - terminal_row = 0; - } } uint32_t vga_seek(vfs_node_t* node, uint32_t offset, int whence) { - terminal_row = offset / VGA_WIDTH; - terminal_column = offset % VGA_WIDTH; return 0; } @@ -105,6 +85,5 @@ uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* bu for (uint32_t i = 0; i < size; i++) { vga_putchar((char)buf[i]); } - update_cursor(); return size; } \ No newline at end of file diff --git a/kernel/drivers/vga/vga.h b/kernel/drivers/vga/vga.h index 403f135..8d61ab3 100644 --- a/kernel/drivers/vga/vga.h +++ b/kernel/drivers/vga/vga.h @@ -3,7 +3,15 @@ #include -void vga_init(); +void vga_init( + uint32_t fb_vaddr, + uint32_t fb_width, + uint32_t fb_height, + uint32_t fb_pitch, + uint8_t fb_bpp +); + +void vga_clear_scrn(uint32_t color); void vga_putchar(char c); uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf); diff --git a/kernel/kmain.c b/kernel/kmain.c index 8a604ca..72e2398 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -97,12 +97,23 @@ void load_root_program(const char* path) { void kmain(uint32_t magic, multiboot_info* mbi) { disable_interrupts(); - if (!(mbi->flags & (1 << 6))) { + + vga_init(mbi->framebuffer_addr, + mbi->framebuffer_width, + mbi->framebuffer_height, + mbi->framebuffer_pitch, + mbi->framebuffer_bpp); + + if (magic != 0x2BADB002) { + return; + } + + // need mmap and fb info + if (!(mbi->flags & (1 << 6)) || !(mbi->flags & (1 << 12))) { return; } - vga_init(); - + return; uint32_t mmap_virtual_addr = mbi->mmap_addr + 0xC0000000; init_pmm((void*)mmap_virtual_addr, mbi->mmap_length); kprintf("memory detection complete. total free memory: %dMB\n", total_free_memory() / 1024 / 1024); diff --git a/kernel/multiboot.h b/kernel/multiboot.h index 4bce159..da4f5f4 100644 --- a/kernel/multiboot.h +++ b/kernel/multiboot.h @@ -17,6 +17,29 @@ typedef struct { uint32_t shndx; uint32_t mmap_length; uint32_t mmap_addr; + uint32_t drives_length; + uint32_t drives_addr; + uint32_t config_table; + uint32_t boot_loader_name; + uint32_t apm_table; + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; + uint8_t red_field_position; + uint8_t red_mask_size; + uint8_t green_field_position; + uint8_t green_mask_size; + uint8_t blue_field_position; + uint8_t blue_mask_size; } __attribute__((packed)) multiboot_info; typedef struct { diff --git a/kernel/syscall.c b/kernel/syscall.c index f12ce07..75f497f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -95,6 +95,25 @@ static int32_t sys_brk(uint32_t new_break) { return current->heap_end; } +static int32_t sys_sbrk(int32_t inc) { + process_t* current = current_task(); + + if (inc <= 0) { // can't shrink yet + return current->heap_end; + } + + uint32_t page_start = (current->heap_end + 4095) & ~4095; + current->heap_end += inc; + uint32_t page_end = (current->heap_end + 4095) & ~4095; + + for (uint32_t addr = page_start; addr < page_end; addr += 4096) { + void* phys = p_alloc_frame(); + map_page(addr, (uint32_t)phys, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER); + } + + return current->heap_end; +} + static int32_t sys_pty(int* slave_fd) { pty_t* pty = (pty_t*)kalloc(sizeof(pty_t)); ring_buf_init(&pty->master_rb); @@ -230,6 +249,7 @@ void syscall(registers_t* regs) { case 5: ret = sys_open((const char*)regs->ebx, regs->ecx); break; case 6: ret = sys_close(regs->ebx); break; case 12: ret = sys_brk(regs->ebx); break; + case 13: ret = sys_sbrk(regs->ebx); break; case 20: ret = sys_pty((int*)regs->ebx); break; case 21: ret = sys_fork(regs); break; case 22: ret = sys_exec(regs, (const char*)regs->ebx); break; diff --git a/programs/lib/rlibc.a b/programs/lib/rlibc.a index f55aebb7bb51dd303d8317a18af3fdd49e66a4d2..feb953199c37985b068199586cd3d6c8a49a0ad4 100644 GIT binary patch literal 7276 zcmcIpeQZ$Iy3P-=Gp;5!m=*Zgdj#xR_fA?1_;I}2?>epXFgi7 zX0jvY$+8qp{d1Zo?Y~W%_ybvK)ky}U#L?)QW!)Mr6Msx9OBytVjzI>f-tYI`z0Skr z3)UX#`rLExx#ymH-#O>rd%UK)DI7fc;*uBK4})(<G?7wbzd4)y0 z-N%*)Ayx~a?VY(S>Jx%x@%utJ-g*4;%}6>WwFf)T3!wInGa=$gNEZ=3+!i`b z6m0J_5qX;0+B$-wIUEX^O-;H8oomrWM<-a%hFkQI2#1xk$B!*}yLSH`P1CTA7HFbaOjAPKF0$IUnP{UZ6Qz>V zLILBGR}Ur{U5RK}_o%)mQR^^1(=wjqrS{HE|a=3aN zE26g_=C$OR^F>|GRKURrlaA-R@967|KN=&OuE%a@y3?7eb@UV`{aRI4U)J2)T_mD+xk!DzzxAk&#z5g*n!_|oP)Ju5X#?M$sK zjt@sa)3W_S7}-SQgTah7pJ8heb$^4v$Zsq7`gbI}9 zu#jhfYfz3$8crxKqP!$&H!uz9>yq98>;}C{(jMSW(7PqAj5tWwTBxT9Pvm^N-gF!o zzG32%s-}m|>B4iONpBLKL#K7jw@{$&P*FT32h;#xVuJ*i#A|@rTrBC^ zHXb%9l6z2wG9TX-IYxaJ%3Fap1(c_XbWgLZ3`7@d)R*lgDAaK=ikcHu(Sy$ItVmG$ z@tfNDem@JJ72p;gZ>lOPWq_YQ-W;Ri02OZ*n>%K;@fY@g=+%R+fz?8bxc(de>?uyUH_UL%w6mvpD~lB%r{f5KnZosQnb=vFcIAeYM-1IaxOqhzf~ z#ICwxQ#t*D@m85}-`Fuw$8RMD>bQ+!VyWdv1AdcChHfYQj>AWeHcJ1p$;><|bCa;ryFq9wvGwT2*5iqaUgFKv^{_)!b3_0oZwDSoKNjCd0N6z65^1= zzmWJh67yS|NOp9VCK-D=1MGzCnw~!d{8u&WF&r_PRSX?NDF(3=R&1hG^ zxd??ZU@g8!mDOebDn5kSV3WS^7*O#TF<_gVWR4hs2;jo;eb98=AO9#9b!a0EmP?PA zr{0tJi1LZGSgAVW)Y7?!UsVJ!X?eSY4_LcFq^^Uw2MPyRieM1*ts;JiIgYC@)2_K5 z1*YC03hjCfZS0%Ru1_dI5-WQswCmaUycowZ#02s!#IDbQuK|U2%@9$7LVX{xYqZg~ z6)61*?Rp9fGurj}ND%k;ykXCKm-bcQMopOiY}+q`gR<*K?$UkK*1X`Aeb6=WdB8W^ zhj1y3KdCm;wAE438|dRMu&>ZZQX7AR?gGE z%If!xO2w4w@-E)TlVL9TUqQcbSZbJGo{|#iqi4<4zjPk?^w5XqUr5-<$8rpY9p1`4 z%?g0_$hbkwLhVU&7rZFcmNb2@!A84L@3hhDQSU`jXYCf$FWP7?>O&~Y&7zrixk+39 zPSjm6C4ODb_kCcmjjjXT09wi43z~OvMT>}Zg5dxEaGfjWeG%vQOn3Ac)}p{AD{Fw+ ztj_0*jfX6XEWD%7#>a2MG5i(;@+~Bejew8eik>xR97E@R3YMVsD~w|+v7njm@_Yt$ zoXUqW_k3||hb^ZvUrxXbQ_ySHI41AtCAgy_F7cZFF4&!^W${60oVPx__6AYCw+G&{-L5u zbFc4?Z`974D8~}IzlZmNZ*<}YMs>X?qEi_2y9I@dylwGQ+TYUZuFZP`KbCoquu?o< zs@u%uGt@=FY(BGD8KGoUWTDT@##iVwt^eglk#)p}G=0r=! zw98EU4Dyiq44Rcqv+`(F+tIVIvp>y)9H4y0A=Ig1wewwTe9V{a7NdR$@4ZGNkTo(e zvQpDGP#rc#jOaC(-`(g?@=b4Y-=WyO#m+q+CN2#1?BD+9s{4_@B`#zWfosXykF+bs zf6Z~uR8g|=BV?L-cIAvAWXGy9(FyHtf2oLF-SY4|(|lL&Ph3D|sWhH;##bW*CF>o& zJ4XGb-sDlOdY!Yo9b4y2)v+G`DeAGYVD+lA%blroZf!SLqP!?}vn1AE)LL|?Ra1{^ zsgGYvzQt77Z}HS+Hjq!~Ga^xc$;ieomm~yc>rOijKcx59X1{ZHBpDb?UdX=7+xggE zK8F(ycU{N|9r-bpZz~nXmFR!8zhcstZ4*xXOli~H3;Cu>+Vm_vwFAl8fmW?yTE+23 zIJp&z3iOHp0n<|rI)`y@Z2z<(hA-XRYv%ndJ;oytl3$OD>lt>&e}!>K5<26*M#Yzw zc|zkd^zMgdKYZDy#m5jX^LmR7VdE(>nE6qwzg0WQi?L0_JLEwAF}mkHx(+mN zhCz*I(QK}-FW*|59se#Amh-&_W-g;wDc$LxJcWen-NDRYAEe|m8&5~u+BV^}d<>tLfpG}PUS?{u_vh;~ zjP0e&C&+DLR34c9=9_}>CQ1<%vO%$sjx5`X5tVqq>q0@^*Sv2%C;Nz8DBnU!qmOZt z_p!~u3fPbM&%hHDQN5$d)7cc(k&%^2e(V1NmFhSDHxO4bM1vZC2QI>QuZN1nZ%e!g zbCF&z@h)HuPldgbHYEKaX}MVDUHFc)T zM*oD43e4{bqVRp)hRx+VxZSiU?lt#$out*hbc3p(oj_hf;rn_vK69_ZUv7?q%|V{B zXEsqDi(g`;x)*$}p-lnxBk=9O@ii!f_t9|?m~A|d)jEEFI^}YHLJ#CE5u8hEePoSvrL|2Qd{C`GTQr#Kz!IvQW=`Yr7_l#GBlE z-Z}T4-#O=(bKYFth0?I?*alZswNx#MVwK2N_9=>zt4_0u;@(_Bh(HKMx!mU8CglHa z;}jvrsYBg|_VvCq_{Fn>ck3O!hY!5z>mmEQefwVTI!uoEP~Y!-t1=Z`s;yhh6S}Bi zsM&~_Rn(d3U0@Bjh zxJh)hyy7Vrr8GNch!&iIQ>GT!qW8j(-pn&jUW7q|07HVA_Gw)7X)9SlbYHNr5&}e$$N435BYB1OBoj&qgsQlO~yMg!KFD?yYEZ$ zok}7_3xiS~#`iFMHr()oRqA0gRE+x;8nX9tw(R@N_cFdiXnR7FzL8U~k`g1{v-Lg< z7eB{`@v9YnDz?#EaIbjV)@!I!Y_mC(Tn-`K2*>0HDOrT=%JiC)Y(q))guI&4KT7F; zetCR#Bh~&5IXc8jtp@nmV5I@Lx5m!7b#T*AM%}R4X6N1b$Ow{AfIgd #include #include #include @@ -23,16 +24,14 @@ void parse_cmd() { return; } - // need a strcat - char* dst = path; - strcpy(dst, bin_dir); - dst = path + strlen(bin_dir); - strcpy(dst, buf); + strcpy(path, bin_dir); + strcat(path, buf); int pid = fork(); if (pid == 0) { if (!exec(path)) { - return; + printf("failed to execute %s\n", path); + exit(0); } } diff --git a/rocklibc/compile_commands.json b/rocklibc/compile_commands.json index 471f792..c1d5345 100644 --- a/rocklibc/compile_commands.json +++ b/rocklibc/compile_commands.json @@ -16,6 +16,40 @@ "file": "/home/slinky/source/RockOS/rocklibc/src/string.c", "output": "/home/slinky/source/RockOS/rocklibc/src/string.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Iinclude", + "-c", + "-o", + "src/malloc.o", + "src/malloc.c" + ], + "directory": "/home/slinky/source/RockOS/rocklibc", + "file": "/home/slinky/source/RockOS/rocklibc/src/malloc.c", + "output": "/home/slinky/source/RockOS/rocklibc/src/malloc.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Iinclude", + "-c", + "-o", + "src/strcat.o", + "src/strcat.c" + ], + "directory": "/home/slinky/source/RockOS/rocklibc", + "file": "/home/slinky/source/RockOS/rocklibc/src/strcat.c", + "output": "/home/slinky/source/RockOS/rocklibc/src/strcat.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -33,6 +67,23 @@ "file": "/home/slinky/source/RockOS/rocklibc/src/syscall.c", "output": "/home/slinky/source/RockOS/rocklibc/src/syscall.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Iinclude", + "-c", + "-o", + "src/strtok.o", + "src/strtok.c" + ], + "directory": "/home/slinky/source/RockOS/rocklibc", + "file": "/home/slinky/source/RockOS/rocklibc/src/strtok.c", + "output": "/home/slinky/source/RockOS/rocklibc/src/strtok.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", diff --git a/rocklibc/include/stdlib.h b/rocklibc/include/stdlib.h new file mode 100644 index 0000000..a6ebd4a --- /dev/null +++ b/rocklibc/include/stdlib.h @@ -0,0 +1,8 @@ +#ifndef RLIBC_STDLIB_H +#define RLIBC_STDLIB_H + +#include + +void* malloc(size_t size); + +#endif \ No newline at end of file diff --git a/rocklibc/include/string.h b/rocklibc/include/string.h index e633f4b..6ab6e20 100644 --- a/rocklibc/include/string.h +++ b/rocklibc/include/string.h @@ -10,5 +10,6 @@ void *memset(void *s, int c, size_t n); size_t strlen(const char *s); int strcmp(const char *s1, const char *s2); char *strcpy(char *dest, const char *src); +char* strcat(char *dest, const char* src); #endif \ No newline at end of file diff --git a/rocklibc/include/syscall.h b/rocklibc/include/syscall.h index 65fe48d..1ff4d32 100644 --- a/rocklibc/include/syscall.h +++ b/rocklibc/include/syscall.h @@ -9,6 +9,8 @@ #define SYS_WRITE 4 #define SYS_OPEN 5 #define SYS_CLOSE 6 +#define SYS_BRK 12 +#define SYS_SBRK 13 #define SYS_PTY 20 #define SYS_FORK 21 #define SYS_EXEC 22 @@ -25,7 +27,7 @@ int lseek(int fd, size_t offset, int whence); void exit(int status) __attribute__((noreturn)); -void *sbrk(intptr_t increment); +void* sbrk(int32_t increment); int brk(void *addr); int pty(int* slave); diff --git a/rocklibc/src/malloc.c b/rocklibc/src/malloc.c new file mode 100644 index 0000000..3fa4ecb --- /dev/null +++ b/rocklibc/src/malloc.c @@ -0,0 +1,74 @@ +#include +#include + +#define ALIGN(size) (((size) + 3) & ~3) +#define HEADER_SIZE sizeof(struct Header) + +struct Header { + size_t size; + int is_free; + struct Header* next; +}; + +static struct Header* free_list_head = NULL; + +static struct Header* find_free_block(struct Header** last, size_t size) { + struct Header* current = free_list_head; + while (current && !(current->is_free && current->size >= size)) { + *last = current; + current = current->next; + } + return current; +} + +static struct Header* request_space(struct Header* last, size_t size) { + struct Header* block = sbrk(0); + void* request = sbrk(size + HEADER_SIZE); + + if (request == (void*)-1) { + return NULL; + } + + if (last) { + last->next = block; + } + + block->size = size; + block->next = NULL; + block->is_free = 0; + return block; +} + +void* malloc(size_t size) { + if (size <= 0) { + return NULL; + } + + size = ALIGN(size); + + if (free_list_head == NULL) { + struct Header* block = request_space(NULL, size); + if (!block) return NULL; + free_list_head = block; + return (void*)(block + 1); + } + + struct Header* last = free_list_head; + struct Header* block = find_free_block(&last, size); + + if (block) { + block->is_free = 0; + } else { + block = request_space(last, size); + if (!block) return NULL; + } + + return (void*)(block + 1); +} + +void free(void* ptr) { + if (!ptr) return; + + struct Header* block = (struct Header*)ptr - 1; + block->is_free = 1; +} \ No newline at end of file diff --git a/rocklibc/src/strcat.c b/rocklibc/src/strcat.c new file mode 100644 index 0000000..e31409f --- /dev/null +++ b/rocklibc/src/strcat.c @@ -0,0 +1,8 @@ +#include +#include + +char* strcat(char* dest, const char* src) { + char* start = dest + strlen(dest); + strcpy(start, src); + return dest; +} \ No newline at end of file diff --git a/rocklibc/src/strtok.c b/rocklibc/src/strtok.c new file mode 100644 index 0000000..641f0d8 --- /dev/null +++ b/rocklibc/src/strtok.c @@ -0,0 +1,63 @@ +#include + +static size_t kernel_strspn(const char *s, const char *accept) { + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) { + for (a = accept; *a != '\0'; ++a) { + if (*p == *a) + break; + } + if (*a == '\0') + return count; + ++count; + } + return count; +} + +static char *kernel_strpbrk(const char *s, const char *accept) { + while (*s != '\0') { + const char *a = accept; + while (*a != '\0') { + if (*s == *a) { + return (char *)s; + } + a++; + } + s++; + } + return NULL; +} + +char *strtok_r(char *str, const char *delim, char **saveptr) { + char *token; + + if (str == NULL) { + str = *saveptr; + } + + if (str == NULL || *str == '\0') { + *saveptr = NULL; + return NULL; + } + + str += kernel_strspn(str, delim); + if (*str == '\0') { + *saveptr = NULL; + return NULL; + } + + token = str; + str = kernel_strpbrk(token, delim); + + if (str == NULL) { + *saveptr = NULL; + } else { + *str = '\0'; + *saveptr = str + 1; + } + + return token; +} \ No newline at end of file diff --git a/rocklibc/src/syscall.c b/rocklibc/src/syscall.c index e2b3063..87f67ff 100644 --- a/rocklibc/src/syscall.c +++ b/rocklibc/src/syscall.c @@ -65,4 +65,12 @@ int dup2(int src, int dst) { int waitpid(int pid, int* status) { return syscall3(SYS_WAIT, pid, (uint32_t)status, 0); +} + +void* sbrk(int32_t increment) { + return (void*)syscall1(SYS_SBRK, increment); +} + +int brk(void *addr) { + return syscall1(SYS_BRK, (uint32_t)addr); } \ No newline at end of file