From 736155ce99ab1a581354f8c816820029eb79086f Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Tue, 2 Oct 2012 23:17:25 -0400 Subject: [PATCH] console: Initial commit of simple framebuffer console output --- include/console.h | 1 + kernel/console.c | 131 ++++++++++++++++++++++++++++++++---------- kernel/start_kernel.c | 22 ++++--- 3 files changed, 115 insertions(+), 39 deletions(-) diff --git a/include/console.h b/include/console.h index 1c51982..6d8179d 100644 --- a/include/console.h +++ b/include/console.h @@ -22,5 +22,6 @@ #define CONSOLE_H void console_init(struct fb *f); +void console_putc(char c); #endif /* CONSOLE_H */ diff --git a/kernel/console.c b/kernel/console.c index 657fda8..a3a69d9 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -20,19 +20,23 @@ #include #include +#include +#include -#define CONSOLE_BUFFER_SIZE 16384 -char console_buffer[CONSOLE_BUFFER_SIZE]; -char console_output_buffer[CONSOLE_BUFFER_SIZE]; -char *console_buffer_p = console_buffer; -struct fb *console_framebuffer = 0; -struct font *console_font = 0; -unsigned int chars_per_line = 0, lines = 0; +char *console_buffer, *cb_first_line; +struct fb *console_framebuffer; +struct font *console_font; +unsigned int chars_per_line, lines; +unsigned int curr_char, curr_line; -void console_char_to_fb(char c, unsigned int x, unsigned int y) { +void console_char_to_fb(char c, unsigned int chr, unsigned int line) { + unsigned int x, y; unsigned int cx, cy, bit = 0; char *font_char = &console_font->data[console_font->bytes_per_char * (c - console_font->ascii_offset)]; + x = chr * console_font->width; + y = line * console_font->height; + for (cy = 0; cy < console_font->height; cy++) { for (cx = 0; cx < console_font->width; cx++) { unsigned char on = font_char[bit / 8] & (1 << (bit % 8)); @@ -45,36 +49,103 @@ void console_char_to_fb(char c, unsigned int x, unsigned int y) { } } -void console_refresh_fb() { +void console_redraw_fb() { + unsigned int cc, cl = 0; + char *c; + if (!console_framebuffer) return; -} -void console_clear() { - int i; - for (i = 0; i < CONSOLE_BUFFER_SIZE; i++) { - console_buffer[i] = 0; + for (c = cb_first_line; c < console_buffer + chars_per_line * lines; c += chars_per_line) { + char *d; + cc = 0; + for (d = c; d < c + chars_per_line; d++) + console_char_to_fb(*d, cc++, cl); + cl++; + } + + for (c = console_buffer; c < cb_first_line; c += chars_per_line) { + char *d; + cc = 0; + for (d = c; d < c + chars_per_line; d++) + console_char_to_fb(*d, cc++, cl); + cl++; } } -void console_init(struct fb *f) { - console_clear(); - console_refresh_fb(); - console_font = font_get(); - console_framebuffer = f; - chars_per_line = console_framebuffer->width / console_font->width; - lines = console_framebuffer->height / console_font->height; +void console_buffer_clear() { + char *c; + for (c = console_buffer; c < console_buffer + chars_per_line * lines; c++) + *c = ' '; + curr_char = 0; + curr_line = 0; +} - console_char_to_fb('A', 100, 100); - console_char_to_fb('E', 111, 100); - console_char_to_fb('D', 122, 100); - console_char_to_fb('R', 133, 100); - console_char_to_fb('I', 144, 100); - console_char_to_fb('X', 155, 100); +int console_init(struct fb *f) { + console_framebuffer = f; + console_font = font_get(); + lines = console_framebuffer->height / console_font->height; + chars_per_line = console_framebuffer->width / console_font->width; + curr_line = 0; + curr_char = 0; + + if (!(console_buffer = kmalloc(sizeof(char) * chars_per_line * lines))) { + print("Error: Failed to allocate memory for console buffer\n"); + return -1; + } + cb_first_line = console_buffer; + + console_buffer_clear(); + console_redraw_fb(); + + return 0; +} + +void console_newline() { + char *c; + + curr_line++; + curr_char = 0; + if (curr_line == lines) { + char *console_buffer_end = console_buffer + chars_per_line * lines; + + //empty the current first line, since it will wrap around to the bottom + for (c = cb_first_line; c < cb_first_line + chars_per_line; c++) + *c = ' '; + + cb_first_line += chars_per_line; + if (cb_first_line >= console_buffer_end) + cb_first_line = console_buffer; + + curr_line = lines - 1; + + console_redraw_fb(); + } } void console_putc(char c) { - *console_buffer_p = c; - if (++console_buffer_p > console_buffer + CONSOLE_BUFFER_SIZE) - console_buffer_p = console_buffer; + char *console_buffer_end = console_buffer + chars_per_line * lines; + char *write_char_at; + + switch (c) { + case '\n': + console_newline(); + return; + case '\r': + curr_char = 0; + return; + default: + break; + } + + if (curr_char + 1 > chars_per_line) + console_newline(); + + write_char_at = cb_first_line + chars_per_line * curr_line + curr_char; + if (write_char_at >= console_buffer_end) + write_char_at -= chars_per_line * lines; + + *write_char_at = c; + + console_char_to_fb(c, curr_char++, curr_line); } diff --git a/kernel/start_kernel.c b/kernel/start_kernel.c index 3a6ebba..4080c44 100644 --- a/kernel/start_kernel.c +++ b/kernel/start_kernel.c @@ -31,15 +31,17 @@ struct fb myfb; -void video(void) { - unsigned int x, y; +void print_console_logo() { + print_func(&console_putc, " _ _ _\n"); + print_func(&console_putc, " / \\ ___ __| |_ __(_)_ __\n"); + print_func(&console_putc, " / _ \\ / _ \\/ _` | '__| \\ \\/ /\n"); + print_func(&console_putc, " / ___ \\ __/ (_| | | | |> <\n"); + print_func(&console_putc, " /_/ \\_\\___|\\__,_|_| |_/_/\\_\\\n\n"); + print_func(&console_putc, " Copyright (C) 2012 - Aaron Lindsay\n"); +} + +void video_init(void) { bcm2835_videocore_init(&myfb, 16); - - for (y = 0; y < myfb.height; y++) - for (x = 0; x < myfb.width; x++) - fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); - - console_init(&myfb); } void test_mm() { @@ -142,7 +144,9 @@ int main(void) { test_memory(); - video(); + video_init(); + console_init(&myfb); + print_console_logo(); return 0; }