From 3b0685a3f0b8a7a6d12ac02f24e979bfbcd043a9 Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Thu, 23 May 2019 17:12:06 +0300 Subject: [PATCH] Multiboot VBE framebuffer support --- src/boot/bootstrap.s | 5 +++-- src/kernlib/display.cpp | 11 +++++++++++ src/platform/pagetable.cpp | 12 ++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/boot/bootstrap.s b/src/boot/bootstrap.s index 6a3b1a9..2a8098d 100644 --- a/src/boot/bootstrap.s +++ b/src/boot/bootstrap.s @@ -12,8 +12,8 @@ _start: .align 4 multiboot_header: .long 0x1BADB002 - .long 0x00010003 - .long -(0x1BADB002+0x00010003) + .long 0x00010005 + .long -(0x1BADB002+0x00010005) .long multiboot_header .long __text_start__ @@ -21,6 +21,7 @@ multiboot_header: .long __bss_end__ + 0x80000 .long multiboot_entry + .long 0, 800, 600, 8 multiboot_entry: cli diff --git a/src/kernlib/display.cpp b/src/kernlib/display.cpp index 52c2755..26304d0 100644 --- a/src/kernlib/display.cpp +++ b/src/kernlib/display.cpp @@ -3,6 +3,7 @@ #include "kernlib.hpp" #include "efi.hpp" +#include "multiboot_info.hpp" #include "pagetable.hpp" #include "font-8x16.hpp" @@ -203,6 +204,16 @@ void Display::setup() { instance = new FramebufferDisplay(fb->base, fb->width, fb->height, pixelFormat); return; } + const struct Multiboot::Payload *mb = Multiboot::getPayload(); + if (mb && (mb->flags & Multiboot::FLAG_VBETAB)) { + const Multiboot::VBEModeInfo *mode = reinterpret_cast(mb->vbe.pmode_info); + if (mode && mode->lfb_ptr) { + instance = new FramebufferDisplay( + reinterpret_cast(mode->lfb_ptr), + mode->h_res, mode->v_res, PixelFormatBGRX); + return; + } + } // Fallback instance = new ConsoleDisplay(); diff --git a/src/platform/pagetable.cpp b/src/platform/pagetable.cpp index 2d9705e..3baa6b7 100644 --- a/src/platform/pagetable.cpp +++ b/src/platform/pagetable.cpp @@ -348,6 +348,18 @@ void Pagetable::init() { mmap += ent->size + sizeof(ent->size); } } + if (multiboot->flags & Multiboot::FLAG_VBETAB) { + if (multiboot->vbe.pcontrol_info < 0x80000) + multiboot->vbe.pcontrol_info += bss_end; + if (multiboot->vbe.pmode_info < 0x80000) + multiboot->vbe.pmode_info += bss_end; + Multiboot::VBEInfo *vbe = reinterpret_cast(multiboot->vbe.pcontrol_info); + map(vbe); map(vbe+1); + const char *vendor = reinterpret_cast(vbe->vendor_string); + map(vendor); + Multiboot::VBEModeInfo *mode = reinterpret_cast(multiboot->vbe.pmode_info); + map(mode); map(mode + 1); + } } }