summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-02-04 23:07:25 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-02-04 23:07:25 +0100
commitf36a96b59eddd066354018c4e6c6279897b33487 (patch)
tree3a55ab20f7e9f91e1131d0fa6873c0b92393af7f
parent4b0929187b70588bcebfe004ab216f3590c01038 (diff)
Added framebuffer.
Output is now to a framebuffer instead of serial console.
-rw-r--r--kernel/SConscript1
-rw-r--r--kernel/framebuffer.c74
-rw-r--r--kernel/framebuffer.h10
-rwxr-xr-xkernel/kernel.h2
-rwxr-xr-xkernel/kernel.ld7
-rw-r--r--kernel/main.c9
-rwxr-xr-xkernel/paging.c1
-rw-r--r--kernel/printf.c26
8 files changed, 109 insertions, 21 deletions
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;
}