diff --git a/kernel/Makefile b/kernel/Makefile index a724437..363ef25 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,8 +2,8 @@ SOURCES_S := boot.s boot64.s OBJECTS_S := $(patsubst %.s, $(BUILD_DIR)/kernel/%.o, $(SOURCES_S)) -SOURCES_C := kernel.c -HEADERS_C := multiboot.h psf.h +SOURCES_C := kernel.c kprintf.c console.c +HEADERS_C := multiboot.h psf.h kprintf.h console.h OBJECTS_C := $(patsubst %.c, $(BUILD_DIR)/kernel/%.o, $(SOURCES_C)) LINKER_LD := linker.ld diff --git a/kernel/console.c b/kernel/console.c new file mode 100644 index 0000000..48e4862 --- /dev/null +++ b/kernel/console.c @@ -0,0 +1,119 @@ +#include "console.h" +#include "psf.h" +#include + +/* graphics framebuffer */ +char *fb; +/* number of bytes in each line */ +int scanline; + +uint32_t console_y; +uint32_t console_x; + +uint32_t console_rows; +uint32_t console_cols; + +multiboot_info_t *mbi; + +psf_font_t *font; + +void putchar (uint16_t c, int32_t cx, int32_t cy, uint32_t fg, uint32_t bg) +{ + uint32_t bytesperline = (font->width + 7) / 8; + + unsigned char *glyph = (unsigned char *)font + font->headersize + + (c > 0 && c < font->numglyphs ? c : 0) * font->bytesperglyph; + + uint32_t offs = (cy * font->height * scanline) + (cx * (font->width) * sizeof (PIXEL)); + + uint32_t x, y, line, mask; + for (y = 0; y < font->height; y++) { + line = offs; + mask = 1 << (font->width -1); + for (x = 0; x < font->width; x++) { + *((PIXEL *)(fb+line)) = *((uint32_t *)glyph) & mask ? fg : bg; + mask >>= 1; + line += sizeof (PIXEL); + } + glyph += bytesperline; + offs += scanline; + } + +} + +void set_pixel(uint64_t x, uint64_t y, PIXEL color) +{ + uint32_t pos = (y * sizeof (PIXEL) * mbi->framebuffer_width) + (x * sizeof (PIXEL)); + *((PIXEL *)(fb+pos)) = color; +} + +PIXEL get_pixel(uint64_t x, uint64_t y) +{ + uint32_t pos = (y * sizeof (PIXEL) * mbi->framebuffer_width) + (x * sizeof (PIXEL)); + return *((PIXEL *)(fb+pos)); +} + +void console_scroll() +{ + const uint32_t width = mbi->framebuffer_width; + const uint32_t font_height = font->height; + + /* Move each row to the previous one */ + for (uint32_t row = 1; row < console_rows; row++) { + for (uint32_t y = 0; y < font_height; y++ ) { + for (uint32_t x = 0; x < width; x++ ) { + PIXEL p = get_pixel(x, (row * font_height) + y); + set_pixel(x, ((row - 1) * font_height) + y, p); + } + } + } + + /* Reset bottom row*/ + for (uint32_t y = 0; y < font_height; y++ ) { + for (uint32_t x = 0; x < width; x++ ) { + set_pixel(x, ((console_rows - 1) * font_height) + y, CONSOLE_BG); + } + } +} + +void console_puts(uint16_t ch) +{ + if (ch == '\n') { + console_x = 0; + console_y++; + return; + } + + if (console_x >= console_cols) { + console_x = 0; + console_y++; + } + + if (console_y >= console_rows) + console_scroll(); + + putchar((uint16_t) ch, console_x, console_y, CONSOLE_FG, CONSOLE_BG); + console_x++; +} + +void console_write(char *str) +{ + for (int idx = 0; str[idx] != '\0'; idx++ ) { + console_puts(str[idx]); + } +} + +void console_init(multiboot_info_t *multiboot_struct) +{ + mbi = multiboot_struct; + fb = (char *)mbi->framebuffer_addr; + scanline = mbi->framebuffer_pitch; + + font = (psf_font_t *)&consolefonts_binary__start; + + console_rows = mbi->framebuffer_height / font->height; + console_cols = mbi->framebuffer_width / font->width; + + console_x = 0; + console_y = 0; +} diff --git a/kernel/console.h b/kernel/console.h new file mode 100644 index 0000000..dacc652 --- /dev/null +++ b/kernel/console.h @@ -0,0 +1,17 @@ +#include "multiboot.h" + +#ifndef CONSOLE_HEADER +#define CONSOLE_HEADER 1 + +#define PIXEL uint32_t + +#define CONSOLE_BG 0 +#define CONSOLE_FG 0xFFFFFFFF + +void console_init(multiboot_info_t *mbi); + +void console_write(char *str); + +void console_puts(uint16_t ch); + +#endif diff --git a/kernel/kernel.c b/kernel/kernel.c index e0e5b3d..02527c7 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,7 +1,6 @@ #include "multiboot.h" -#include "psf.h" -#include -#include +#include "console.h" +#include "kprintf.h" #if defined (__linux__) #error "You are not using a cross-compiler, you will most certainly run into trouble" @@ -11,203 +10,8 @@ #error "The kernel needs to be compiled with a x86_64-elf compiler" #endif -/* graphics framebuffer */ -char *fb; -/* number of bytes in each line */ -int scanline; -/* extern the symbols in the psf object */ -extern char consolefonts_binary__start; -extern char consolefonts_binary__end; - -multiboot_info_t *mbi; -uint32_t console_y; -uint32_t console_x; - -uint32_t console_rows; -uint32_t console_cols; - -#define PIXEL uint32_t - -#define CONSOLE_BG 0 -#define CONSOLE_FG 0xFFFFFFFF - -void putchar (uint16_t c, int32_t cx, int32_t cy, uint32_t fg, uint32_t bg) -{ - psf_font_t *font = (psf_font_t *)&consolefonts_binary__start; - uint32_t bytesperline = (font->width + 7) / 8; - - unsigned char *glyph = (unsigned char *)&consolefonts_binary__start + font->headersize + - (c > 0 && c < font->numglyphs ? c : 0) * font->bytesperglyph; - - uint32_t offs = (cy * font->height * scanline) + (cx * (font->width) * sizeof (PIXEL)); - - uint32_t x, y, line, mask; - for (y = 0; y < font->height; y++) { - line = offs; - mask = 1 << (font->width -1); - for (x = 0; x < font->width; x++) { - *((PIXEL *)(fb+line)) = *((uint32_t *)glyph) & mask ? fg : bg; - mask >>= 1; - line += sizeof (PIXEL); - } - glyph += bytesperline; - offs += scanline; - } - -} - -void set_pixel(uint64_t x, uint64_t y, PIXEL color) -{ - uint32_t pos = (y * sizeof (PIXEL) * mbi->framebuffer_width) + (x * sizeof (PIXEL)); - *((PIXEL *)(fb+pos)) = color; -} - -PIXEL get_pixel(uint64_t x, uint64_t y) -{ - uint32_t pos = (y * sizeof (PIXEL) * mbi->framebuffer_width) + (x * sizeof (PIXEL)); - return *((PIXEL *)(fb+pos)); -} - -void console_scroll() -{ - const uint32_t height = mbi->framebuffer_height; - const uint32_t width = mbi->framebuffer_width; - const uint32_t font_height = ((psf_font_t *)&consolefonts_binary__start)->height; - - /* Move each row to the previous one */ - for (int row = 1; row < console_rows; row++) { - for (int y = 0; y < font_height; y++ ) { - for (int x = 0; x < width; x++ ) { - PIXEL p = get_pixel(x, (row * font_height) + y); - set_pixel(x, ((row - 1) * font_height) + y, p); - } - } - } - - /* Reset bottom row*/ - for (int y = 0; y < font_height; y++ ) { - for (int x = 0; x < width; x++ ) { - set_pixel(x, ((console_rows - 1) * font_height) + y, CONSOLE_BG); - } - } -} - -void console_puts(uint16_t ch) -{ - if (ch == '\n') { - console_x = 0; - console_y++; - return; - } - - if (console_x >= console_cols) { - console_x = 0; - console_y++; - } - - if (console_y >= console_rows) - console_scroll(); - - putchar((uint16_t) ch, console_x, console_y, CONSOLE_FG, CONSOLE_BG); - console_x++; -} - -void console_write(char *str) -{ - for (int idx = 0; str[idx] != '\0'; idx++ ) { - console_puts(str[idx]); - } -} - -void console_init(multiboot_info_t *mbi) -{ - psf_font_t *font = (psf_font_t *)&consolefonts_binary__start; - - console_rows = mbi->framebuffer_height / font->height; - console_cols = mbi->framebuffer_width / font->width; - - console_x = 0; - console_y = 0; -} - -void convert(uint64_t num, int base, char *buf, int bufsize) -{ - int idx = 0; - buf[idx] = '\0'; - - do { - /* Avoid buffer overrun */ - if (idx == bufsize - 1) - break; - - int remainder = num % base; - - if (remainder > 9) - buf[idx] = remainder - 10 + 'A'; - else - buf[idx] = remainder + '0'; - - num /= base; - idx++; - } while(num != 0); - - buf[idx] = '\0'; - - for (int i = 0; i < idx / 2; i++) { - int tmp = buf[i]; - buf[i] = buf[idx-1-i]; - buf[idx-1-i] = tmp; - } -} - -void kprintf(char *format, ...) -{ - va_list arg; - va_start(arg, format); - - char buffer[50]; - long i; - - for (int idx = 0; format[idx] != '\0'; idx++) { - while (format[idx] != '%') { - - /* Never overrun the buffer */ - if (format[idx] == '\0') - return; - - console_puts(format[idx]); - idx++; - } - idx++; - switch (format[idx]) { - case 'd': - i = va_arg(arg, long); - if (i < 0) { - i = -i; - console_puts('-'); - } - - convert(i, 10, buffer, 50); - console_write(buffer); - break; - case 'X': - i = va_arg(arg, long); - - convert(i, 16, buffer, 50); - console_write(buffer); - break; - } - } - - va_end(arg); -} - void kernel_main (multiboot_info_t *multiboot_struct_addr) { - mbi = multiboot_struct_addr; - fb = (char *)mbi->framebuffer_addr; - scanline = mbi->framebuffer_pitch; - - console_init(mbi); - kprintf("Console width is %d\n", mbi->framebuffer_width); + console_init(multiboot_struct_addr); + kprintf("Hello World"); } diff --git a/kernel/kprintf.c b/kernel/kprintf.c new file mode 100644 index 0000000..704324e --- /dev/null +++ b/kernel/kprintf.c @@ -0,0 +1,76 @@ +#include "console.h" +#include "kprintf.h" +#include +#include + +void convert(uint64_t num, int base, char *buf, int bufsize) +{ + int idx = 0; + buf[idx] = '\0'; + + do { + /* Avoid buffer overrun */ + if (idx == bufsize - 1) + break; + + int remainder = num % base; + + if (remainder > 9) + buf[idx] = remainder - 10 + 'A'; + else + buf[idx] = remainder + '0'; + + num /= base; + idx++; + } while(num != 0); + + buf[idx] = '\0'; + + for (int i = 0; i < idx / 2; i++) { + int tmp = buf[i]; + buf[i] = buf[idx-1-i]; + buf[idx-1-i] = tmp; + } +} + +void kprintf(char *format, ...) +{ + va_list arg; + va_start(arg, format); + + char buffer[50]; + long i; + + for (int idx = 0; format[idx] != '\0'; idx++) { + while (format[idx] != '%') { + + /* Never overrun the buffer */ + if (format[idx] == '\0') + return; + + console_puts(format[idx]); + idx++; + } + idx++; + switch (format[idx]) { + case 'd': + i = va_arg(arg, long); + if (i < 0) { + i = -i; + console_puts('-'); + } + + convert(i, 10, buffer, 50); + console_write(buffer); + break; + case 'X': + i = va_arg(arg, long); + + convert(i, 16, buffer, 50); + console_write(buffer); + break; + } + } + + va_end(arg); +} diff --git a/kernel/kprintf.h b/kernel/kprintf.h new file mode 100644 index 0000000..d0c0037 --- /dev/null +++ b/kernel/kprintf.h @@ -0,0 +1,6 @@ +#ifndef KPRINTF_HEADER +#define KPRINTF_HEADER 1 + +void kprintf(char *format, ...); + +#endif diff --git a/kernel/psf.h b/kernel/psf.h index d2334a1..9a715fc 100644 --- a/kernel/psf.h +++ b/kernel/psf.h @@ -5,6 +5,10 @@ #define PSF_FONT_MAGIC 0x864ab572 +/* extern the symbols in the psf object */ +extern char consolefonts_binary__start; +extern char consolefonts_binary__end; + struct psf_font { uint32_t magic; /* magic bytes to identify psf */ uint32_t version; /* zero */