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 f55aebb..feb9531 100644 Binary files a/programs/lib/rlibc.a and b/programs/lib/rlibc.a differ diff --git a/programs/rocksh/main.c b/programs/rocksh/main.c index 825e782..201dc16 100644 --- a/programs/rocksh/main.c +++ b/programs/rocksh/main.c @@ -1,4 +1,5 @@ #include "syscall.h" +#include #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