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

@@ -11,7 +11,6 @@
- lock `memory_manager` and `page_manager` structures - lock `memory_manager` and `page_manager` structures
- Serial out based on circular/bip biffer and interrupts, not spinning on - Serial out based on circular/bip biffer and interrupts, not spinning on
`write_ready()` `write_ready()`
- Get framebuffer screen working again
- Device Tree - Device Tree

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,33 +18,27 @@
extern "C" { extern "C" {
void do_the_set_registers(popcorn_data *header); void do_the_set_registers(popcorn_data *header);
void kernel_main(popcorn_data *header); void kernel_main(popcorn_data *header);
void *__bss_start, *__bss_end;
} }
/* void
console init_console(const popcorn_data *header)
load_console(const popcorn_data *header)
{ {
console cons{ serial_port *com1 = new (&g_com1) serial_port(COM1);
font::load(header->font), console *cons = new (&g_console) console(com1);
screen{
if (header->frame_buffer) {
screen *s = new screen(
header->frame_buffer, header->frame_buffer,
header->hres, header->hres,
header->vres, header->vres,
header->rmask, header->rmask,
header->gmask, header->gmask,
header->bmask}, header->bmask);
header->log, font *f = new font(header->font);
header->log_length}; cons->init_screen(s, f);
}
return cons;
}
*/
void
kernel_main(popcorn_data *header)
{
serial_port *com1 = new (&g_com1) serial_port(COM1);
console *cons = new (&g_console) console(com1);
cons->set_color(0x21, 0x00); cons->set_color(0x21, 0x00);
cons->puts("Popcorn OS "); cons->puts("Popcorn OS ");
@@ -53,18 +47,15 @@ kernel_main(popcorn_data *header)
log::init(cons); log::init(cons);
log::enable(logs::interrupt, log::level::debug); log::enable(logs::interrupt, log::level::debug);
}
cpu_id cpu; void
kernel_main(popcorn_data *header)
log::info(logs::boot, "CPU Vendor: %s", cpu.vendor_id()); {
log::info(logs::boot, "CPU Family %x Model %x Stepping %x", // First clear BSS
cpu.family(), cpu.model(), cpu.stepping()); kutil::memset(__bss_start, 0,
reinterpret_cast<uint64_t>(__bss_end) -
cpu_id::regs cpu_info = cpu.get(1); reinterpret_cast<uint64_t>(__bss_start));
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");
page_manager *pager = new (&g_page_manager) page_manager; 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_length,
header->memory_map_desc_size); 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(); interrupts_init();
device_manager devices(header->acpi_table); device_manager devices(header->acpi_table);
interrupts_enable(); 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; // int x = 1 / 0;
// __asm__ __volatile__("int $15"); // __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::mapped |
page_block_flags::mmio; 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); m_used = page_block::insert(m_used, block);
page_table *pml4 = get_pml4(); 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::pixel_t
screen::color(uint8_t r, uint8_t g, uint8_t b) const screen::color(uint8_t r, uint8_t g, uint8_t b) const
{ {

View File

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