mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 04:18:43 +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>
|
||||
/// VBE.
|
||||
/// </summary>
|
||||
public readonly IOGroup.VBE VBE = new IOGroup.VBE();
|
||||
public readonly IOGroup.VBEIOGroup VBE = new IOGroup.VBEIOGroup();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
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
|
||||
{
|
||||
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue