summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--include/debug.h11
-rw-r--r--include/graphics.h32
-rw-r--r--include/multiboot2.h40
-rw-r--r--kernel/debug.c21
-rw-r--r--kernel/graphics.c83
-rw-r--r--kernel/main.c100
-rw-r--r--kernel/multiboot2.c39
8 files changed, 239 insertions, 92 deletions
diff --git a/Makefile b/Makefile
index db39540..8c41c59 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
+}