diff --git a/NOTES.md b/NOTES.md index d1488cf..16f3145 100644 --- a/NOTES.md +++ b/NOTES.md @@ -11,7 +11,6 @@ - lock `memory_manager` and `page_manager` structures - Serial out based on circular/bip biffer and interrupts, not spinning on `write_ready()` -- Get framebuffer screen working again - Device Tree diff --git a/src/arch/x86_64/kernel.ld b/src/arch/x86_64/kernel.ld index 8837c3f..049c9b0 100755 --- a/src/arch/x86_64/kernel.ld +++ b/src/arch/x86_64/kernel.ld @@ -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) : { diff --git a/src/kernel/console.cpp b/src/kernel/console.cpp index 03131dd..3d2138f 100644 --- a/src/kernel/console.cpp +++ b/src/kernel/console.cpp @@ -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(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(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(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(attr), static_cast(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 m_size; kutil::coord 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); +} diff --git a/src/kernel/console.h b/src/kernel/console.h index d5459a9..5b3c6a5 100644 --- a/src/kernel/console.h +++ b/src/kernel/console.h @@ -1,11 +1,10 @@ #pragma once #include +#include -#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 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 diff --git a/src/kernel/font.cpp b/src/kernel/font.cpp index 69f2bcd..de571be 100644 --- a/src/kernel/font.cpp +++ b/src/kernel/font.cpp @@ -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(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(data) + psf2->header_size; - return font{ - psf2->height, - psf2->width, - psf2->length, - font_data}; + m_data = static_cast(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); } } } diff --git a/src/kernel/font.h b/src/kernel/font.h index 47fd470..74723a4 100644 --- a/src/kernel/font.h +++ b/src/kernel/font.h @@ -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 m_size; unsigned m_count; uint8_t const *m_data; + + font() = delete; }; diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 2200eb2..1ffae4f 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -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(__bss_end) - + reinterpret_cast(__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"); diff --git a/src/kernel/memory_pages.cpp b/src/kernel/memory_pages.cpp index 6082771..ebec123 100644 --- a/src/kernel/memory_pages.cpp +++ b/src/kernel/memory_pages.cpp @@ -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(); diff --git a/src/kernel/screen.cpp b/src/kernel/screen.cpp index da645f6..4a5ad70 100644 --- a/src/kernel/screen.cpp +++ b/src/kernel/screen.cpp @@ -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 { diff --git a/src/kernel/screen.h b/src/kernel/screen.h index 03bb7ce..ac018bb 100644 --- a/src/kernel/screen.h +++ b/src/kernel/screen.h @@ -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 m_resolution; + + screen() = delete; };