From f36a96b59eddd066354018c4e6c6279897b33487 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Thu, 4 Feb 2010 23:07:25 +0100 Subject: Added framebuffer. Output is now to a framebuffer instead of serial console. --- kernel/SConscript | 1 + kernel/framebuffer.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/framebuffer.h | 10 +++++++ kernel/kernel.h | 2 ++ kernel/kernel.ld | 7 ++--- kernel/main.c | 9 ++++--- kernel/paging.c | 1 + kernel/printf.c | 26 ++++++++---------- 8 files changed, 109 insertions(+), 21 deletions(-) create mode 100644 kernel/framebuffer.c create mode 100644 kernel/framebuffer.h diff --git a/kernel/SConscript b/kernel/SConscript index 4d91b9a..df6f10b 100644 --- a/kernel/SConscript +++ b/kernel/SConscript @@ -3,6 +3,7 @@ Import('env') kernel = env.Standalone('kernel', [ 'kernel.ld', 'entry.c', + 'framebuffer.c', 'gdt.c', 'idt.c', 'irq.c', diff --git a/kernel/framebuffer.c b/kernel/framebuffer.c new file mode 100644 index 0000000..220d556 --- /dev/null +++ b/kernel/framebuffer.c @@ -0,0 +1,74 @@ +#include "framebuffer.h" +#include "kernel.h" +#include "portio.h" + +uint16_t framebuffer_color = 0x0700; +uint8_t framebuffer_x; +uint8_t framebuffer_y; + +void framebuffer_init() { + union {uint8_t b[2]; uint16_t w;} pos; + + outb(0x3d4, 0x0f); + inb(0x3d5, pos.b[0]); + + outb(0x3d4, 0x0e); + inb(0x3d5, pos.b[1]); + + framebuffer_x = pos.w % 80; + framebuffer_y = pos.w / 80; +} + +void framebuffer_putchar(char c) { + switch(c) { + case '\f': + framebuffer_clear(); + break; + case '\r': + framebuffer_x = 0; + break; + case '\n': + framebuffer_x = 80; + break; + default: + framebuffer[framebuffer_y][framebuffer_x++] = framebuffer_color | c; + } + if(framebuffer_x == 80) { + framebuffer_x = 0; + if(framebuffer_y < 24) { + framebuffer_y++; + } else { + framebuffer_scroll(); + } + } +} + +void framebuffer_clear() { + for(int y = 0; y < 25; y++) { + for(int x = 0; x < 80; x++) { + framebuffer[y][x] = framebuffer_color; + } + } + framebuffer_x = framebuffer_y = 0; +} + +void framebuffer_scroll() { + for(int y = 0; y < 24; y++) { + for(int x = 0; x < 80; x++) { + framebuffer[y][x] = framebuffer[y + 1][x]; + } + } + for(int x = 0; x < 80; x++) { + framebuffer[24][x] = framebuffer_color; + } +} + +void framebuffer_move_cursor() { + uint16_t pos = framebuffer_y * 80 + framebuffer_x; + + outb(0x3d4, 0x0f); + outb(0x3d5, pos & 0xff); + + outb(0x3d4, 0x0e); + outb(0x3d5, pos >> 8); +} diff --git a/kernel/framebuffer.h b/kernel/framebuffer.h new file mode 100644 index 0000000..c57a187 --- /dev/null +++ b/kernel/framebuffer.h @@ -0,0 +1,10 @@ +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + +void framebuffer_init(); +void framebuffer_putchar(char c); +void framebuffer_clear(); +void framebuffer_scroll(); +void framebuffer_move_cursor(); + +#endif diff --git a/kernel/kernel.h b/kernel/kernel.h index ac313b1..3770c59 100755 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -23,4 +23,6 @@ extern uint32_t entry_map_p1[2][1024]; extern volatile uint32_t map_p2[1024]; extern volatile union {uint32_t l[1024]; uint32_t b[1024][1024];} map_p1; +extern uint16_t framebuffer[25][80]; + #endif diff --git a/kernel/kernel.ld b/kernel/kernel.ld index 3054aec..616d0a1 100755 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -59,8 +59,9 @@ SECTIONS { multiboot_info = .; . += 0x1000; . = 0x100000000; - stack_top = .; . -= 0x400000; - map_p2 = .; . -= 0x400000; - map_p1 = .; + stack_top = .; . -= 0x800000; + map_p1 = .; . += 0x400000; + map_p2 = .; . += 0x1000; + framebuffer = .; . += 0x1000; } diff --git a/kernel/main.c b/kernel/main.c index d6de534..e5695b6 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,4 +1,5 @@ #include "kernel.h" +#include "framebuffer.h" #include "printf.h" #include "palloc.h" #include "paging.h" @@ -6,15 +7,17 @@ #include "idt.h" #include "irq.h" +#include "portio.h" + void main() { + paging_reinit(); + + framebuffer_init(); printf("main()\n"); palloc_init(); printf("Page allocator initiated.\n"); - paging_reinit(); - printf("Paging reinitialized.\n"); - gdt_init(); printf("GDT set.\n"); diff --git a/kernel/paging.c b/kernel/paging.c index ca09936..88da0ab 100755 --- a/kernel/paging.c +++ b/kernel/paging.c @@ -5,6 +5,7 @@ void paging_reinit() { map_p1.l[(uint32_t)&map_p2 >> 12] = (uint32_t)&entry_map_p2 | P1_P | P1_W | P1_G; + map_p1.l[(uint32_t)&framebuffer >> 12] = 0xb8000 | P1_P | P1_W | P1_G; invlpg(&map_p2); diff --git a/kernel/printf.c b/kernel/printf.c index 0b51f8d..61237aa 100644 --- a/kernel/printf.c +++ b/kernel/printf.c @@ -1,13 +1,6 @@ #include "printf.h" #include "types.h" -#include "portio.h" - -void putchar(char c) { - if(c == '\n') { - outb(0x3f8, '\r'); - } - outb(0x3f8, c); -} +#include "framebuffer.h" int printf(const char* format, ...) { int32_t* argp = (int32_t*)&format; @@ -15,7 +8,7 @@ int printf(const char* format, ...) { while(*format) { if(*format != '%') { - putchar(*format++); + framebuffer_putchar(*format++); num++; continue; } @@ -36,12 +29,12 @@ int printf(const char* format, ...) { switch(*format++) { case '%': - putchar('%'); + framebuffer_putchar('%'); num++; break; case 'c': - putchar((char)*++argp); + framebuffer_putchar((char)*++argp); num++; break; @@ -49,7 +42,7 @@ int printf(const char* format, ...) { ; char* str = (char*)*++argp; while(*str) { - putchar(*str++); + framebuffer_putchar(*str++); num++; } break; @@ -63,7 +56,7 @@ int printf(const char* format, ...) { uint32_t x = (uint32_t)*(++argp); if(is_signed && (int32_t)x < 0) { x = -x; - putchar('-'); + framebuffer_putchar('-'); min_len--; } @@ -79,17 +72,20 @@ int printf(const char* format, ...) { } while(x); while(min_len > 0) { - putchar(zero_pad ? '0' : ' '); + framebuffer_putchar(zero_pad ? '0' : ' '); num++; min_len--; } while(*bufp) { - putchar(*bufp++); + framebuffer_putchar(*bufp++); num++; } break; } } + + framebuffer_move_cursor(); + return num; } -- cgit v1.2.3