Re-integrate framebuffer console

This commit is contained in:
Justin C. Miller
2018-05-03 22:01:33 -07:00
parent a6b915f6b4
commit 33012f35ef
10 changed files with 141 additions and 173 deletions

View File

@@ -5,24 +5,24 @@ SECTIONS
. = OFFSET + 0x100000;
.header : {
header = .;
__header_start = .;
KEEP(*(.header))
__header_end = .;
}
.text : {
code = .;
*(.text)
}
.data ALIGN(0x1000) : {
data = .;
*(.data)
*(.rodata)
}
.bss ALIGN(0x1000) : {
bss = .;
__bss_start = .;
*(.bss)
__bss_end = .;
}
.note ALIGN(0x1000) : {

View File

@@ -1,89 +1,96 @@
#include "kutil/coord.h"
#include "kutil/memory.h"
#include "console.h"
#include "font.h"
#include "memory.h"
#include "screen.h"
#include "serial.h"
const char digits[] = "0123456789abcdef";
console g_console;
class console_out_screen
class console::screen_out
{
public:
console_out_screen(const font &f, const screen &s, void *scratch, size_t len) :
screen_out(screen *s, font *f) :
m_font(f),
m_screen(s),
m_size(s.width() / f.width(), s.height() / f.height()),
m_size(s->width() / f->width(), s->height() / f->height()),
m_fg(0xffffff),
m_bg(0),
m_first(0),
m_length(len),
m_data(nullptr),
m_attrs(nullptr),
m_palette(nullptr)
{
const unsigned count = m_size.size();
const size_t palette_size = sizeof(screen::pixel_t) * 256;
const size_t attrs_size = 2 * count;
if (len >= count) {
// We have enough scratch space to keep the contents of the screen
m_data = static_cast<char *>(scratch);
for (unsigned i = 0; i < count; ++i)
m_data[i] = 0;
}
m_data = new char[count];
kutil::memset(m_data, 0, count);
if (len >= count + palette_size + attrs_size) {
// We have enough scratch space to also keep the colors of the text
m_palette = reinterpret_cast<screen::pixel_t *>(m_data + count);
m_palette = new screen::pixel_t[256];
fill_palette();
unsigned index = 0;
// Manually add the 16 basic ANSI colors
m_palette[index++] = m_screen.color(0x00, 0x00, 0x00);
m_palette[index++] = m_screen.color(0xcd, 0x00, 0x00);
m_palette[index++] = m_screen.color(0x00, 0xcd, 0x00);
m_palette[index++] = m_screen.color(0xcd, 0xcd, 0x00);
m_palette[index++] = m_screen.color(0x00, 0x00, 0xee);
m_palette[index++] = m_screen.color(0xcd, 0x00, 0xcd);
m_palette[index++] = m_screen.color(0x00, 0xcd, 0xcd);
m_palette[index++] = m_screen.color(0xe5, 0xe5, 0xe5);
m_palette[index++] = m_screen.color(0x7f, 0x7f, 0x7f);
m_palette[index++] = m_screen.color(0xff, 0x00, 0x00);
m_palette[index++] = m_screen.color(0x00, 0xff, 0x00);
m_palette[index++] = m_screen.color(0xff, 0xff, 0x00);
m_palette[index++] = m_screen.color(0x00, 0x50, 0xff);
m_palette[index++] = m_screen.color(0xff, 0x00, 0xff);
m_palette[index++] = m_screen.color(0x00, 0xff, 0xff);
m_palette[index++] = m_screen.color(0xff, 0xff, 0xff);
// Build the high-color portion of the table
const uint32_t intensity[] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff};
const uint32_t intensities = sizeof(intensity) / sizeof(uint32_t);
for (uint32_t r = 0; r < intensities; ++r) {
for (uint32_t g = 0; g < intensities; ++g) {
for (uint32_t b = 0; b < intensities; ++b) {
m_palette[index++] = m_screen.color(
intensity[r], intensity[g], intensity[b]);
}
}
}
// Build the greyscale portion of the table
for (uint8_t i = 0x08; i <= 0xee; i += 10)
m_palette[index++] = m_screen.color(i, i, i);
set_color(7, 0); // Grey on black default
m_attrs = reinterpret_cast<uint16_t *>(m_data + count + palette_size);
for (unsigned i = 0; i < count; ++i)
m_attrs[i] = m_attr;
}
m_attrs = new uint16_t[count];
set_color(7, 0); // Grey on black default
for (unsigned i = 0; i < count; ++i) m_attrs[i] = m_attr;
repaint();
}
~screen_out()
{
delete [] m_data;
delete [] m_palette;
delete [] m_attrs;
}
void fill_palette()
{
unsigned index = 0;
// Manually add the 16 basic ANSI colors
m_palette[index++] = m_screen->color(0x00, 0x00, 0x00);
m_palette[index++] = m_screen->color(0xcd, 0x00, 0x00);
m_palette[index++] = m_screen->color(0x00, 0xcd, 0x00);
m_palette[index++] = m_screen->color(0xcd, 0xcd, 0x00);
m_palette[index++] = m_screen->color(0x00, 0x00, 0xee);
m_palette[index++] = m_screen->color(0xcd, 0x00, 0xcd);
m_palette[index++] = m_screen->color(0x00, 0xcd, 0xcd);
m_palette[index++] = m_screen->color(0xe5, 0xe5, 0xe5);
m_palette[index++] = m_screen->color(0x7f, 0x7f, 0x7f);
m_palette[index++] = m_screen->color(0xff, 0x00, 0x00);
m_palette[index++] = m_screen->color(0x00, 0xff, 0x00);
m_palette[index++] = m_screen->color(0xff, 0xff, 0x00);
m_palette[index++] = m_screen->color(0x00, 0x50, 0xff);
m_palette[index++] = m_screen->color(0xff, 0x00, 0xff);
m_palette[index++] = m_screen->color(0x00, 0xff, 0xff);
m_palette[index++] = m_screen->color(0xff, 0xff, 0xff);
// Build the high-color portion of the table
const uint32_t intensity[] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff};
const uint32_t intensities = sizeof(intensity) / sizeof(uint32_t);
for (uint32_t r = 0; r < intensities; ++r) {
for (uint32_t g = 0; g < intensities; ++g) {
for (uint32_t b = 0; b < intensities; ++b) {
m_palette[index++] = m_screen->color(
intensity[r], intensity[g], intensity[b]);
}
}
}
// Build the greyscale portion of the table
for (uint8_t i = 0x08; i <= 0xee; i += 10)
m_palette[index++] = m_screen->color(i, i, i);
}
void repaint()
{
m_screen.fill(m_bg);
m_screen->fill(m_bg);
if (!m_data) return;
for (unsigned y = 0; y < m_size.y; ++y) {
@@ -95,13 +102,13 @@ public:
set_color(static_cast<uint8_t>(attr),
static_cast<uint8_t>(attr >> 8));
m_font.draw_glyph(
m_font->draw_glyph(
m_screen,
line[x] ? line[x] : ' ',
m_fg,
m_bg,
x * m_font.width(),
y * m_font.height());
x * m_font->width(),
y * m_font->height());
}
}
}
@@ -156,9 +163,9 @@ public:
if (line) line[m_pos.x] = c;
if (attrs) attrs[m_pos.x] = m_attr;
const unsigned x = m_pos.x * m_font.width();
const unsigned y = m_pos.y * m_font.height();
m_font.draw_glyph(m_screen, c, m_fg, m_bg, x, y);
const unsigned x = m_pos.x * m_font->width();
const unsigned y = m_pos.y * m_font->height();
m_font->draw_glyph(m_screen, c, m_fg, m_bg, x, y);
m_pos.x++;
}
@@ -188,8 +195,8 @@ private:
return m_attrs + ((m_first + line) % m_size.y) * m_size.x;
}
font m_font;
screen m_screen;
font *m_font;
screen *m_screen;
kutil::coord<unsigned> m_size;
kutil::coord<unsigned> m_pos;
@@ -197,21 +204,12 @@ private:
uint16_t m_attr;
size_t m_first;
size_t m_length;
char *m_data;
uint16_t *m_attrs;
screen::pixel_t *m_palette;
};
console_out_screen *
console_get_screen_out(const font &f, const screen &s, void *scratch, size_t len)
{
return nullptr;
//return new console_out_screen(f, s, scratch, len);
}
console::console() :
m_screen(nullptr),
@@ -357,3 +355,9 @@ void console::vprintf(const char *fmt, va_list args)
flush();
}
void
console::init_screen(screen *s, font *f)
{
m_screen = new screen_out(s, f);
}

View File

@@ -1,11 +1,10 @@
#pragma once
#include <stdarg.h>
#include <stdint.h>
#include "kutil/coord.h"
#include "font.h"
#include "screen.h"
class console_out_screen;
class font;
struct kernel_data;
class screen;
class serial_port;
class console
@@ -34,14 +33,15 @@ public:
template <typename T>
void put_dec(T x, int width = 0);
void set_screen(console_out_screen *out) { m_screen = out; }
void echo();
void init_screen(screen *s, font *f);
static console * get();
private:
console_out_screen *m_screen;
class screen_out;
screen_out *m_screen;
serial_port *m_serial;
};
@@ -49,10 +49,6 @@ extern console g_console;
inline console * console::get() { return &g_console; }
console_out_screen * console_get_screen_out(
const font &f, const screen &s, void *scratch, size_t len);
extern const char digits[];
template <typename T>

View File

@@ -1,3 +1,4 @@
#include "assert.h"
#include "font.h"
/* PSF2 header format
@@ -26,44 +27,26 @@ struct psf2_header {
uint32_t height, width; // max dimensions of glyphs
};
font
font::load(void const *data)
font::font(void const *data) :
m_size(0, 0),
m_count(0),
m_data(nullptr)
{
psf2_header const *psf2 = static_cast<psf2_header const *>(data);
for (int i = 0; i < sizeof(magic); ++i) {
if (psf2->magic[i] != magic[i]) {
return font{};
}
kassert(psf2->magic[i] == magic[i], "Bad font magic number.");
}
uint8_t const *font_data = static_cast<uint8_t const *>(data) + psf2->header_size;
return font{
psf2->height,
psf2->width,
psf2->length,
font_data};
m_data = static_cast<uint8_t const *>(data) + psf2->header_size;
m_size.x = psf2->width;
m_size.y = psf2->height;
m_count = psf2->length;
}
font::font() :
m_count(0),
m_data(nullptr)
{}
font::font(unsigned height, unsigned width, unsigned count, uint8_t const *data) :
m_size(width, height),
m_count(count),
m_data(data)
{}
font::font(const font &other) :
m_size(other.m_size),
m_count(other.m_count),
m_data(other.m_data)
{}
void
font::draw_glyph(
screen &s,
screen *s,
uint32_t glyph,
screen::pixel_t fg,
screen::pixel_t bg,
@@ -80,7 +63,7 @@ font::draw_glyph(
if (dx*8 + i >= m_size.x) continue;
const uint8_t mask = 1 << (7-i);
uint32_t c = (byte & mask) ? fg : bg;
s.draw_pixel(x + dx*8 + i, y + dy, c);
s->draw_pixel(x + dx*8 + i, y + dy, c);
}
}
}

View File

@@ -7,8 +7,7 @@
class font
{
public:
static font load(void const *data);
font(const font &other);
font(void const *data);
unsigned glyph_bytes() const { return m_size.y * ((m_size.x + 7) / 8); }
unsigned count() const { return m_count; }
@@ -17,7 +16,7 @@ public:
bool valid() const { return m_count > 0; }
void draw_glyph(
screen &s,
screen *s,
uint32_t glyph,
screen::pixel_t fg,
screen::pixel_t bg,
@@ -25,11 +24,10 @@ public:
unsigned y) const;
private:
font();
font(unsigned height, unsigned width, unsigned count, uint8_t const *data);
kutil::coord<unsigned> m_size;
unsigned m_count;
uint8_t const *m_data;
font() = delete;
};

View File

@@ -18,34 +18,28 @@
extern "C" {
void do_the_set_registers(popcorn_data *header);
void kernel_main(popcorn_data *header);
}
/*
console
load_console(const popcorn_data *header)
{
console cons{
font::load(header->font),
screen{
header->frame_buffer,
header->hres,
header->vres,
header->rmask,
header->gmask,
header->bmask},
header->log,
header->log_length};
return cons;
void *__bss_start, *__bss_end;
}
*/
void
kernel_main(popcorn_data *header)
init_console(const popcorn_data *header)
{
serial_port *com1 = new (&g_com1) serial_port(COM1);
console *cons = new (&g_console) console(com1);
if (header->frame_buffer) {
screen *s = new screen(
header->frame_buffer,
header->hres,
header->vres,
header->rmask,
header->gmask,
header->bmask);
font *f = new font(header->font);
cons->init_screen(s, f);
}
cons->set_color(0x21, 0x00);
cons->puts("Popcorn OS ");
cons->set_color(0x08, 0x00);
@@ -53,18 +47,15 @@ kernel_main(popcorn_data *header)
log::init(cons);
log::enable(logs::interrupt, log::level::debug);
}
cpu_id cpu;
log::info(logs::boot, "CPU Vendor: %s", cpu.vendor_id());
log::info(logs::boot, "CPU Family %x Model %x Stepping %x",
cpu.family(), cpu.model(), cpu.stepping());
cpu_id::regs cpu_info = cpu.get(1);
log::info(logs::boot, "LAPIC Supported: %s",
cpu_info.edx_bit(9) ? "yes" : "no");
log::info(logs::boot, "x2APIC Supported: %s",
cpu_info.ecx_bit(21) ? "yes" : "no");
void
kernel_main(popcorn_data *header)
{
// First clear BSS
kutil::memset(__bss_start, 0,
reinterpret_cast<uint64_t>(__bss_end) -
reinterpret_cast<uint64_t>(__bss_start));
page_manager *pager = new (&g_page_manager) page_manager;
@@ -73,13 +64,21 @@ kernel_main(popcorn_data *header)
header->memory_map_length,
header->memory_map_desc_size);
pager->map_offset_pointer(&header->frame_buffer, header->frame_buffer_length);
pager->map_offset_pointer(
&header->frame_buffer,
header->frame_buffer_length);
init_console(header);
interrupts_init();
device_manager devices(header->acpi_table);
interrupts_enable();
cpu_id cpu;
log::info(logs::boot, "CPU Vendor: %s", cpu.vendor_id());
log::info(logs::boot, "CPU Family %x Model %x Stepping %x",
cpu.family(), cpu.model(), cpu.stepping());
// int x = 1 / 0;
// __asm__ __volatile__("int $15");

View File

@@ -228,8 +228,6 @@ page_manager::map_offset_pointer(void **pointer, size_t length)
page_block_flags::mapped |
page_block_flags::mmio;
log::debug(logs::memory, "Fixing up pointer %lx [%3d] -> %lx", *p, c, v);
m_used = page_block::insert(m_used, block);
page_table *pml4 = get_pml4();

View File

@@ -46,13 +46,6 @@ screen::screen(
{
}
screen::screen(const screen &other) :
m_framebuffer(other.m_framebuffer),
m_masks(other.m_masks),
m_resolution(other.m_resolution)
{
}
screen::pixel_t
screen::color(uint8_t r, uint8_t g, uint8_t b) const
{

View File

@@ -14,8 +14,6 @@ public:
unsigned hres, unsigned vres,
pixel_t rmask, pixel_t gmask, pixel_t bmask);
screen(const screen &other);
unsigned width() const { return m_resolution.x; }
unsigned height() const { return m_resolution.y; }
@@ -24,8 +22,6 @@ public:
void fill(pixel_t color);
void draw_pixel(unsigned x, unsigned y, pixel_t color);
screen() = delete;
private:
struct color_masks {
uint8_t rshift, gshift, bshift;
@@ -37,4 +33,6 @@ private:
pixel_t *m_framebuffer;
color_masks m_masks;
kutil::coord<unsigned> m_resolution;
screen() = delete;
};