diff options
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | include/debug.h | 11 | ||||
| -rw-r--r-- | include/graphics.h | 32 | ||||
| -rw-r--r-- | include/multiboot2.h | 40 | ||||
| -rw-r--r-- | kernel/debug.c | 21 | ||||
| -rw-r--r-- | kernel/graphics.c | 83 | ||||
| -rw-r--r-- | kernel/main.c | 100 | ||||
| -rw-r--r-- | kernel/multiboot2.c | 39 |
8 files changed, 239 insertions, 92 deletions
@@ -10,7 +10,7 @@ CFLAGS = -Wall -Werror -Wno-error=infinite-recursion -O -fno-omit-frame-pointer # -mgeneral-regs-only disables SIMD instructions CFLAGS += -MD -O3 -mgeneral-regs-only CFLAGS += -ffreestanding -fno-common -nostdlib -CFLAGS += -I. +CFLAGS += -I include CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) CFLAGS += -fno-pie -no-pie -fno-pic LDFLAGS = -z max-page-size=4096 @@ -22,6 +22,9 @@ OBJS = \ $K/boot.o \ $K/boot64.o \ $K/main.o \ + $K/graphics.o \ + $K/multiboot2.o \ + $K/debug.o \ kernel.iso: kernel.bin $K/grub.cfg mkdir -p isodir/boot/grub diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..1c53148 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,11 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include <stdint.h> + +void bochs_breakpoint(void); +void put_in_r8(uint64_t value); +void put_in_r9(uint64_t value); +void put_in_r10(uint64_t value); + +#endif diff --git a/include/graphics.h b/include/graphics.h new file mode 100644 index 0000000..d00e8d8 --- /dev/null +++ b/include/graphics.h @@ -0,0 +1,32 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include <stdint.h> + +struct fb_t { + uint64_t addr; + uint32_t pitch; + uint32_t width; + uint32_t height; + uint8_t bpp; + uint8_t type; +} __attribute__((packed, aligned(8))); +typedef struct fb_t fb_t; + +extern fb_t fb; + +#define RED 0x00ff0000 +#define GREEN 0x0000ff00 +#define BLUE 0x000000ff +#define YELLOW 0x00ffff00 +#define PURPLE 0x00ff00ff +#define WHITE 0x00ffffff +#define BLACK 0x00000000 + +uint64_t* pixel_offset(fb_t fb, uint32_t x, uint32_t y); +void fb_draw_pixel(fb_t fb, uint32_t x, uint32_t y, uint32_t col); +void fb_draw_line_low(fb_t fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t col); +void fb_draw_line_high(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col); +void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col); + +#endif diff --git a/include/multiboot2.h b/include/multiboot2.h new file mode 100644 index 0000000..f22fd8e --- /dev/null +++ b/include/multiboot2.h @@ -0,0 +1,40 @@ +#ifndef MULTIBOOT2_H +#define MULTIBOOT2_H + +#include <stdint.h> + +struct mb2_tag_header { + uint32_t type; + uint32_t size; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_header mb2_tag_header; + +struct mb2_tag_fb { + uint32_t type; + uint32_t size; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_fb mb2_tag_fb; + +// multiboot2 magic check +#define MB2_MAGIC 0x36D76289 + +// multiboot2 tag +#define MB2_TAG_END 0 +#define MB2_TAG_CMDLINE 1 +#define MB2_TAG_BOOTLOADER 2 +#define MB2_TAG_MODULES 3 +#define MB2_TAG_MEM 4 +#define MB2_TAG_BIOS 5 +#define MB2_TAG_MMAP 6 +#define MB2_TAG_VBE 7 +#define MB2_TAG_FB 8 + +void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic); + +#endif diff --git a/kernel/debug.c b/kernel/debug.c new file mode 100644 index 0000000..3ce4866 --- /dev/null +++ b/kernel/debug.c @@ -0,0 +1,21 @@ +#include <stdint.h> + +void bochs_breakpoint(void) +{ + __asm__ volatile ("xchgw %bx, %bx;"); +} + +void put_in_r8(uint64_t value) +{ + __asm__ volatile ("movq %0, %%r8;" : : "r"(value) : "%r8"); +} + +void put_in_r9(uint64_t value) +{ + __asm__ volatile ("movq %0, %%r9;" : : "r"(value) : "%r9"); +} + +void put_in_r10(uint64_t value) +{ + __asm__ volatile ("movq %0, %%r10;" : : "r"(value) : "%r10"); +} diff --git a/kernel/graphics.c b/kernel/graphics.c new file mode 100644 index 0000000..da5ed5d --- /dev/null +++ b/kernel/graphics.c @@ -0,0 +1,83 @@ +#include <stdint.h> +#include <multiboot2.h> +#include <graphics.h> +#include <debug.h> + +uint64_t* pixel_offset(fb_t fb, uint32_t x, uint32_t y) +{ + return (uint64_t*)((uint32_t*)fb.addr + y * fb.pitch / 4 + x); +} + +void fb_draw_pixel(fb_t fb, uint32_t x, uint32_t y, uint32_t col) +{ + uint64_t* fb_offset = pixel_offset(fb, x, y); + *fb_offset = col; +} + +void fb_draw_line_low(fb_t fb, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t col) +{ + uint32_t dx = x1 - x0; + uint32_t dy = y1 - y0; + uint32_t yi = 1; + if (dy < 0) { + yi = -1; + dy = -dy; + } + uint32_t D = (2 * dy) - dx; + uint32_t y = y0; + + for (uint32_t x = x0; x < x1; x++) { + fb_draw_pixel(fb, x, y, col); + if (D > 0) { + y = y + yi; + D = D + (2 * (dy - dx)); + } else { + D = D + 2*dy; + } + } + +} + +void fb_draw_line_high(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) +{ + int32_t dx = x1 - x0; + int32_t dy = y1 - y0; + int32_t xi = 1; + if (dx < 0) { + xi = -1; + dx = -dx; + } + int32_t D = (2 * dx) - dy; + int32_t x = x0; + + for (int32_t y = y0; y <= y1; y++) { + fb_draw_pixel(fb, x, y, col); + if (D > 0) { + x = x + xi; + D = D + (2 * (dx - dy)); + } else { + D = D + 2*dx; + } + } +} + +uint32_t abs(int64_t val) +{ + if (val < 0) return -val; + return val; +} + +void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t col) +{ + if (abs(y1 - y0) < abs(x1 - x0)) { + if (x0 > x1) + fb_draw_line_low(fb, x1, y1, x0, y0, col); + else + fb_draw_line_low(fb, x0, y0, x1, y1, col); + } else { + if (y0 > y1) + fb_draw_line_high(fb, x1, y1, x0, y0, col); + else + fb_draw_line_high(fb, x0, y0, x1, y1, col); + } +} diff --git a/kernel/main.c b/kernel/main.c index 79039e6..d868b42 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,102 +1,20 @@ #include <stdint.h> - -struct mb2_tag_header { - uint32_t type; - uint32_t size; -} __attribute__((packed, aligned(8))); -typedef struct mb2_tag_header mb2_tag_header; - -struct mb2_tag_fb { - uint32_t type; - uint32_t size; - uint64_t framebuffer_addr; - uint32_t framebuffer_pitch; - uint32_t framebuffer_width; - uint32_t framebuffer_height; - uint8_t framebuffer_bpp; - uint8_t framebuffer_type; -} __attribute__((packed, aligned(8))); -typedef struct mb2_tag_fb mb2_tag_fb; - -// multiboot2 magic check -#define MB2_MAGIC 0x36D76289 - -// multiboot2 tag -#define MB2_TAG_END 0 -#define MB2_TAG_CMDLINE 1 -#define MB2_TAG_BOOTLOADER 2 -#define MB2_TAG_MODULES 3 -#define MB2_TAG_MEM 4 -#define MB2_TAG_BIOS 5 -#define MB2_TAG_MMAP 6 -#define MB2_TAG_VBE 7 -#define MB2_TAG_FB 8 - -void breakpoint(void) -{ - __asm__ volatile ("xchgw %bx, %bx;"); -} - -void put_in_r8(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r8;" : : "r"(value) : "%r8"); -} - -void put_in_r9(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r9;" : : "r"(value) : "%r9"); -} - -void put_in_r10(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r10;" : : "r"(value) : "%r10"); -} +#include <multiboot2.h> +#include <graphics.h> +#include <debug.h> int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) { - if (multiboot_magic != MB2_MAGIC) { - // not loaded by multiboot2 bootloader - __asm__ volatile ("hlt;"); - } - - // we will store framebuffer information here - static mb2_tag_fb* tag_fb; + init_fb(multiboot_bootinfo, multiboot_magic); - // skip first 8 bytes (total_size + reserved) - mb2_tag_header* tag_header = multiboot_bootinfo + 1; - - while (tag_header->type != MB2_TAG_END) { - // process tag_type - switch(tag_header->type) { - case MB2_TAG_FB: - tag_fb = (mb2_tag_fb*)tag_header; - break; - default: - break; + static uint32_t color = BLACK; + for (uint32_t x = 0 ; x < fb.width; x++) { + for (uint32_t y = 0; y < fb.height; y++) { + fb_draw_pixel(fb, x, y, color); } - - // next mb2_tag - tag_header += tag_header->size / 8 + ((tag_header->size % 8) > 0); } - uint64_t* framebuffer_addr = (uint64_t*)tag_fb->framebuffer_addr; - uint32_t framebuffer_width = tag_fb->framebuffer_width; - uint32_t framebuffer_height = tag_fb->framebuffer_height; - //uint8_t framebuffer_bpp = tag_fb->framebuffer_bpp; - uint32_t framebuffer_pitch = tag_fb->framebuffer_pitch; - - put_in_r8(framebuffer_width); - put_in_r9(framebuffer_height); - put_in_r10(framebuffer_pitch); - breakpoint(); - - uint32_t value = 0x0000; - for (uint32_t x = 0 ; x < framebuffer_width; x++) { - for (uint32_t y = 0; y < framebuffer_height; y++) { - framebuffer_addr[y*framebuffer_width + x] = value; - value += 0x250; - } - } + fb_draw_line(fb, 0, 0, 100, 1200, WHITE); return 0; } diff --git a/kernel/multiboot2.c b/kernel/multiboot2.c new file mode 100644 index 0000000..9b2e04e --- /dev/null +++ b/kernel/multiboot2.c @@ -0,0 +1,39 @@ +#include <stdint.h> +#include <multiboot2.h> +#include <graphics.h> + +fb_t fb; + +void init_fb(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) +{ + if (multiboot_magic != MB2_MAGIC) { + // not loaded by multiboot2 bootloader + __asm__ volatile ("hlt;"); + } + + // we will store framebuffer information here + static mb2_tag_fb* tag_fb; + + // skip first 8 bytes (total_size + reserved) + mb2_tag_header* tag_header = multiboot_bootinfo + 1; + + while (tag_header->type != MB2_TAG_END) { + // process tag_type + switch(tag_header->type) { + case MB2_TAG_FB: + tag_fb = (mb2_tag_fb*)tag_header; + break; + default: + break; + } + + // next mb2_tag + tag_header += tag_header->size / 8 + ((tag_header->size % 8) > 0); + } + + fb.addr = tag_fb->framebuffer_addr; + fb.width = tag_fb->framebuffer_width; + fb.height = tag_fb->framebuffer_height; + fb.pitch = tag_fb->framebuffer_pitch; + fb.bpp = tag_fb->framebuffer_bpp; +} |
