Merge pull request #1384 from CosmosOS/dev/multibootvbe

Multiboot VBE detection
This commit is contained in:
valentinbreiz 2020-07-06 22:01:28 +02:00 committed by GitHub
commit afff8d9e46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 263 additions and 11 deletions

View file

@ -43,6 +43,6 @@ namespace Cosmos.Core {
/// <summary>
/// VBE.
/// </summary>
public readonly IOGroup.VBE VBE = new IOGroup.VBE();
public readonly IOGroup.VBEIOGroup VBE = new IOGroup.VBEIOGroup();
}
}

View file

@ -1,6 +1,6 @@
namespace Cosmos.Core
{
public static class Bootstrap
public unsafe static class Bootstrap
{
// See note in Global - these are a "hack" for now so
// we dont force static init of Global, and it "pulls" these later till
@ -9,6 +9,11 @@
// Has to be static for now, ZeroFill gets called before the Init.
static public readonly CPU CPU = new CPU();
public static Multiboot.Header* header;
public static VBE.ModeInfo* modeinfo;
public static VBE.ControllerInfo* controllerinfo;
// Bootstrap is a class designed only to get the essentials done.
// ie the stuff needed to "pre boot". Do only the very minimal here.
// IDT, PIC, and Float
@ -32,6 +37,11 @@
*/
CPU.InitFloat();
header = (Multiboot.Header*)Multiboot.GetMBIAddress();
modeinfo = (Core.VBE.ModeInfo*)header->vbeModeInfo;
controllerinfo = (Core.VBE.ControllerInfo*)header->vbeControlInfo;
// Managed_Memory_System.ManagedMemory.Initialize();
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
}

View file

@ -10,7 +10,7 @@ namespace Cosmos.Core.IOGroup
/// <summary>
/// VBE class.
/// </summary>
public class VBE : IOGroup
public class VBEIOGroup : IOGroup
{
/// <summary>
/// Index IOPort.
@ -27,7 +27,7 @@ namespace Cosmos.Core.IOGroup
/// <summary>
/// Frame buffer memory block.
/// </summary>
public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4);
public MemoryBlock LinearFrameBuffer;
//public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1024 * 768 * 4);
}
}

View file

@ -0,0 +1,199 @@
using IL2CPU.API.Attribs;
using System;
using System.Runtime.InteropServices;
namespace Cosmos.Core
{
/// <summary>
/// Used for Multiboot parsing
/// </summary>
public class Multiboot
{
/// /// <summary>
/// Get Multiboot address. Plugged.
/// </summary>
/// <returns>The Multiboot Address</returns>
[PlugMethod(PlugRequired = true)]
public static uint GetMBIAddress() => throw null;
[StructLayout(LayoutKind.Explicit, Size = 88)]
public unsafe struct Header
{
[FieldOffset(0)]
public uint Flags;
[FieldOffset(4)]
public uint mem_lower;
[FieldOffset(8)]
public uint mem_upper;
[FieldOffset(12)]
public uint boot_device;
[FieldOffset(16)]
public uint cmdline;
[FieldOffset(20)]
public uint mods_count;
[FieldOffset(24)]
public uint mods_addr;
[FieldOffset(28)]
public fixed uint syms[4];
[FieldOffset(44)]
public uint memMapLength;
[FieldOffset(48)]
public uint memMapAddress;
[FieldOffset(52)]
public uint drivesLength;
[FieldOffset(56)]
public uint drivesAddress;
[FieldOffset(60)]
public uint configTable;
[FieldOffset(68)]
public uint apmTable;
[FieldOffset(72)]
public uint vbeControlInfo;
[FieldOffset(76)]
public uint vbeModeInfo;
[FieldOffset(80)]
public uint vbeMode;
[FieldOffset(82)]
public uint vbeInterfaceSeg;
[FieldOffset(84)]
public uint vbeInterfaceOff;
[FieldOffset(86)]
public uint vbeInterfaceLength;
}
}
public unsafe static class VBE
{
static uint VBEINFO_PRESENT = (1 << 11);
/// /// <summary>
/// Check in Multiboot if VBE is available
/// </summary>
/// <returns>True if is available, false if not</returns>
public static bool IsAvailable()
{
if ((Bootstrap.header->Flags & VBEINFO_PRESENT) == 0)
{
return false;
}
else
{
return true;
}
}
/// /// <summary>
/// Get VBE Modeinfo structure
/// </summary>
public static ModeInfo getModeInfo()
{
return *Bootstrap.modeinfo;
}
/// /// <summary>
/// Get the linear frame buffer address from VBE ModeInfo structure
/// </summary>
/// <returns>the offset in an uint</returns>
public static uint getLfbOffset()
{
return Bootstrap.modeinfo->framebuffer;
}
[StructLayout(LayoutKind.Explicit, Size = 36)]
public struct ControllerInfo
{
[FieldOffset(0)]
public uint vbeSignature;
[FieldOffset(4)]
public ushort vbeVersion;
[FieldOffset(6)]
public uint oemStringPtr;
[FieldOffset(10)]
public uint capabilities;
[FieldOffset(14)]
public uint videoModePtr;
[FieldOffset(18)]
public ushort totalmemory;
[FieldOffset(20)]
public ushort oemSoftwareRev;
[FieldOffset(24)]
public uint oemVendorNamePtr;
[FieldOffset(28)]
public uint oemProductNamePtr;
[FieldOffset(32)]
public uint oemProductRevPtr;
}
[StructLayout(LayoutKind.Explicit, Size = 256)]
public struct ModeInfo
{
[FieldOffset(0)]
public ushort attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
[FieldOffset(2)]
public byte window_a; // deprecated
[FieldOffset(3)]
public byte window_b; // deprecated
[FieldOffset(4)]
public ushort granularity; // deprecated; used while calculating bank numbers
[FieldOffset(6)]
public ushort window_size;
[FieldOffset(8)]
public ushort segment_a;
[FieldOffset(10)]
public ushort segment_b;
[FieldOffset(12)]
public uint win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode
[FieldOffset(16)]
public ushort pitch; // number of bytes per horizontal line
[FieldOffset(18)]
public ushort width; // width in pixels
[FieldOffset(20)]
public ushort height; // height in pixels
[FieldOffset(22)]
public byte w_char; // unused...
[FieldOffset(23)]
public byte y_char; // ...
[FieldOffset(24)]
public byte planes;
[FieldOffset(25)]
public byte bpp; // bits per pixel in this mode
[FieldOffset(26)]
public byte banks; // deprecated; total number of banks in this mode
[FieldOffset(27)]
public byte memory_model;
[FieldOffset(28)]
public byte bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
[FieldOffset(29)]
public byte image_pages;
[FieldOffset(30)]
public byte reserved0;
[FieldOffset(31)]
public byte red_mask;
[FieldOffset(32)]
public byte red_position;
[FieldOffset(33)]
public byte green_mask;
[FieldOffset(34)]
public byte green_position;
[FieldOffset(35)]
public byte blue_mask;
[FieldOffset(36)]
public byte blue_position;
[FieldOffset(37)]
public byte reserved_mask;
[FieldOffset(38)]
public byte reserved_position;
[FieldOffset(39)]
public byte direct_color_attributes;
[FieldOffset(40)]
public uint framebuffer; // physical address of the linear frame buffer; write here to draw to the screen
[FieldOffset(44)]
public uint off_screen_mem_off;
[FieldOffset(48)]
public ushort off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen
[FieldOffset(50)]
public fixed byte reserved1[206];
}
}
}

View file

@ -0,0 +1,14 @@
using XSharp.Assembler;
using XSharp;
using CPUx86 = XSharp.Assembler.x86;
namespace Cosmos.Core_Asm
{
public class MultibootAsm : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
new CPUx86.Push { DestinationRef = ElementReference.New("MultiBootInfo_Structure"), DestinationIsIndirect = true };
}
}
}

View file

@ -0,0 +1,12 @@
using Cosmos.Core;
using IL2CPU.API.Attribs;
namespace Cosmos.Core_Asm
{
[Plug(Target = typeof(Multiboot))]
public class MultibootImpl
{
[PlugMethod(Assembler = typeof(MultibootAsm))]
public static uint GetMBIAddress() => throw null;
}
}

View file

@ -12,7 +12,7 @@ namespace Cosmos.HAL.Drivers
public class VBEDriver
{
private static readonly VBE IO = Core.Global.BaseIOGroups.VBE;
private static readonly VBEIOGroup IO = Core.Global.BaseIOGroups.VBE;
ManagedMemoryBlock lastbuffer;
/// <summary>
@ -76,10 +76,19 @@ namespace Cosmos.HAL.Drivers
/// <param name="bpp">BPP (color depth).</param>
public VBEDriver(ushort xres, ushort yres, ushort bpp)
{
Global.mDebugger.SendInternal($"Creating VBEDriver with Mode {xres}*{yres}@{bpp}");
//IO.LinearFrameBuffer = new MemoryBlock(0xE0000000, (uint)xres * yres * (uint)(bpp / 8));
lastbuffer = new ManagedMemoryBlock(1920 * 1200 * 4);
VBESet(xres, yres, bpp);
if (VBE.IsAvailable())
{
Global.mDebugger.SendInternal($"Creating VBE VESA driver with Mode {xres}*{yres}@{bpp}");
IO.LinearFrameBuffer = new MemoryBlock(VBE.getLfbOffset(), (uint)xres * yres * (uint)(bpp / 8));
lastbuffer = new ManagedMemoryBlock((uint)xres * yres * (uint)(bpp / 8));
}
else
{
Global.mDebugger.SendInternal($"Creating VBE BGA driver with Mode {xres}*{yres}@{bpp}");
IO.LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4);
lastbuffer = new ManagedMemoryBlock(1920 * 1200 * 4);
VBESet(xres, yres, bpp);
}
}
/// <summary>

View file

@ -66,7 +66,7 @@ namespace Cosmos.System.Graphics
{
return new SVGAIICanvas();
}
else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null)
else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null || Core.VBE.IsAvailable())
{
return new VBECanvas();
}
@ -88,7 +88,7 @@ namespace Cosmos.System.Graphics
{
return new SVGAIICanvas(mode);
}
else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null)
else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null || Core.VBE.IsAvailable())
{
return new VBECanvas(mode);
}

View file

@ -44,6 +44,13 @@ namespace Cosmos.System.Graphics
{
Global.mDebugger.SendInternal($"Creating new VBEScreen() with mode {aMode.Columns}x{aMode.Rows}x{(uint)aMode.ColorDepth}");
if (Core.VBE.IsAvailable())
{
Core.VBE.ModeInfo ModeInfo = Core.VBE.getModeInfo();
aMode = new Mode(ModeInfo.width, ModeInfo.height, (ColorDepth)ModeInfo.bpp);
Global.mDebugger.SendInternal($"Detected VBE VESA with {aMode.Columns}x{aMode.Rows}x{(uint)aMode.ColorDepth}");
}
ThrowIfModeIsNotValid(aMode);
_VBEDriver = new VBEDriver((ushort)aMode.Columns, (ushort)aMode.Rows, (ushort)aMode.ColorDepth);
@ -122,6 +129,7 @@ namespace Cosmos.System.Graphics
new Mode(1024, 768, ColorDepth.ColorDepth32),
/* The so called HD-Ready resolution */
new Mode(1280, 720, ColorDepth.ColorDepth32),
new Mode(1280, 768, ColorDepth.ColorDepth32),
new Mode(1280, 1024, ColorDepth.ColorDepth32),
/* A lot of HD-Ready screen uses this instead of 1280x720 */
new Mode(1366, 768, ColorDepth.ColorDepth32),