mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +00:00
Merge pull request #1384 from CosmosOS/dev/multibootvbe
Multiboot VBE detection
This commit is contained in:
commit
afff8d9e46
9 changed files with 263 additions and 11 deletions
|
|
@ -43,6 +43,6 @@ namespace Cosmos.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VBE.
|
/// VBE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly IOGroup.VBE VBE = new IOGroup.VBE();
|
public readonly IOGroup.VBEIOGroup VBE = new IOGroup.VBEIOGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Cosmos.Core
|
namespace Cosmos.Core
|
||||||
{
|
{
|
||||||
public static class Bootstrap
|
public unsafe static class Bootstrap
|
||||||
{
|
{
|
||||||
// See note in Global - these are a "hack" for now so
|
// See note in Global - these are a "hack" for now so
|
||||||
// we dont force static init of Global, and it "pulls" these later till
|
// 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.
|
// Has to be static for now, ZeroFill gets called before the Init.
|
||||||
static public readonly CPU CPU = new CPU();
|
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.
|
// Bootstrap is a class designed only to get the essentials done.
|
||||||
// ie the stuff needed to "pre boot". Do only the very minimal here.
|
// ie the stuff needed to "pre boot". Do only the very minimal here.
|
||||||
// IDT, PIC, and Float
|
// IDT, PIC, and Float
|
||||||
|
|
@ -32,6 +37,11 @@
|
||||||
*/
|
*/
|
||||||
CPU.InitFloat();
|
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.Initialize();
|
||||||
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
|
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Cosmos.Core.IOGroup
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VBE class.
|
/// VBE class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class VBE : IOGroup
|
public class VBEIOGroup : IOGroup
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Index IOPort.
|
/// Index IOPort.
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Cosmos.Core.IOGroup
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Frame buffer memory block.
|
/// Frame buffer memory block.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4);
|
public MemoryBlock LinearFrameBuffer;
|
||||||
//public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1024 * 768 * 4);
|
//public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1024 * 768 * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
199
source/Cosmos.Core/Multiboot.cs
Normal file
199
source/Cosmos.Core/Multiboot.cs
Normal 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
source/Cosmos.Core_Asm/Multiboot/MultibootAsm.cs
Normal file
14
source/Cosmos.Core_Asm/Multiboot/MultibootAsm.cs
Normal 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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
source/Cosmos.Core_Asm/MultibootImpl.cs
Normal file
12
source/Cosmos.Core_Asm/MultibootImpl.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Cosmos.HAL.Drivers
|
||||||
public class VBEDriver
|
public class VBEDriver
|
||||||
{
|
{
|
||||||
|
|
||||||
private static readonly VBE IO = Core.Global.BaseIOGroups.VBE;
|
private static readonly VBEIOGroup IO = Core.Global.BaseIOGroups.VBE;
|
||||||
ManagedMemoryBlock lastbuffer;
|
ManagedMemoryBlock lastbuffer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -76,10 +76,19 @@ namespace Cosmos.HAL.Drivers
|
||||||
/// <param name="bpp">BPP (color depth).</param>
|
/// <param name="bpp">BPP (color depth).</param>
|
||||||
public VBEDriver(ushort xres, ushort yres, ushort bpp)
|
public VBEDriver(ushort xres, ushort yres, ushort bpp)
|
||||||
{
|
{
|
||||||
Global.mDebugger.SendInternal($"Creating VBEDriver with Mode {xres}*{yres}@{bpp}");
|
if (VBE.IsAvailable())
|
||||||
//IO.LinearFrameBuffer = new MemoryBlock(0xE0000000, (uint)xres * yres * (uint)(bpp / 8));
|
{
|
||||||
|
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);
|
lastbuffer = new ManagedMemoryBlock(1920 * 1200 * 4);
|
||||||
VBESet(xres, yres, bpp);
|
VBESet(xres, yres, bpp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace Cosmos.System.Graphics
|
||||||
{
|
{
|
||||||
return new SVGAIICanvas();
|
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();
|
return new VBECanvas();
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Cosmos.System.Graphics
|
||||||
{
|
{
|
||||||
return new SVGAIICanvas(mode);
|
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);
|
return new VBECanvas(mode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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}");
|
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);
|
ThrowIfModeIsNotValid(aMode);
|
||||||
|
|
||||||
_VBEDriver = new VBEDriver((ushort)aMode.Columns, (ushort)aMode.Rows, (ushort)aMode.ColorDepth);
|
_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),
|
new Mode(1024, 768, ColorDepth.ColorDepth32),
|
||||||
/* The so called HD-Ready resolution */
|
/* The so called HD-Ready resolution */
|
||||||
new Mode(1280, 720, ColorDepth.ColorDepth32),
|
new Mode(1280, 720, ColorDepth.ColorDepth32),
|
||||||
|
new Mode(1280, 768, ColorDepth.ColorDepth32),
|
||||||
new Mode(1280, 1024, ColorDepth.ColorDepth32),
|
new Mode(1280, 1024, ColorDepth.ColorDepth32),
|
||||||
/* A lot of HD-Ready screen uses this instead of 1280x720 */
|
/* A lot of HD-Ready screen uses this instead of 1280x720 */
|
||||||
new Mode(1366, 768, ColorDepth.ColorDepth32),
|
new Mode(1366, 768, ColorDepth.ColorDepth32),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue