Skip to content
This repository has been archived by the owner on Jun 24, 2024. It is now read-only.

Read and write to IO Ports #14

Open
FrankRay78 opened this issue Mar 27, 2024 · 10 comments
Open

Read and write to IO Ports #14

FrankRay78 opened this issue Mar 27, 2024 · 10 comments
Assignees
Labels

Comments

@FrankRay78
Copy link
Owner

FrankRay78 commented Mar 27, 2024

The ability to read and write to IO ports is needed (nb. this is something different to memory mapped IO).

Switch between VGA text modes is a good example that requires writing to an IO Port.

Various ways exist to do this, namely:

  1. Utilising the ASM plug architecture of COSMOS (see this and this)
  2. Linking to a machine-specific DLL/library (nb. not great because a cross-compiler setup will be needed for each)

Background reading

  1. Read/Write to Debug Port (0x80h) using C#
  2. QEMU_Monitor (OS Dev)
  3. QEMU Monitor Manual

This command demonstrates the ability for QEMU Monitor to dump physical memory addresses:

i/fmt addr [.index]
Read I/O port.

fmt is a format which tells the command how to format the data. Its syntax is: /{count}{format}{size}

I intend to use i 0x80 to validate a successful write to the debug port (0x80h).


Please upvote 👍 this issue if you are interested in it.

@FrankRay78
Copy link
Owner Author

FrankRay78 commented Mar 27, 2024

COSMOS Plug example

namespace Cosmos.Core
{
    /// <summary>
    /// IOPort static class.
    /// </summary>
    public static class IOPort
    {
        /// <summary>
        /// Write byte to port.
        /// Plugged.
        /// </summary>
        /// <param name="aPort">A port to write to.</param>
        /// <param name="aData">A data.</param>
        [PlugMethod(PlugRequired = true)]
        public static void Write8(int aPort, byte aData) => throw null;

and also

namespace Cosmos.Core_Asm
{
    [Plug(Target = typeof(IOPort))]
    public class IOPortImpl
    {
        private class Write8Assembler : AssemblerMethod
        {
            public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
            {
                //TODO: This is a lot of work to write to a single port.
                // We need to have some kind of inline ASM option that can
                // emit a single out instruction
                XS.Set(XSRegisters.EDX, XSRegisters.EBP, sourceDisplacement: 0x0C);
                XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 0x08);
                XS.WriteToPortDX(XSRegisters.AL);
            }
        }

        [PlugMethod(Assembler = typeof(Write8Assembler))]
        public static void Write8(ushort aPort, byte aData) => throw null;

FlingOS Plug example

        /// <summary>
        ///     Writes a byte to the specified port.
        /// </summary>
        /// <param name="port">The port to write to.</param>
        /// <param name="aVal">The value to write.</param>
        [PluggedMethod(ASMFilePath = @"ASM\IO\IOPort\Write")]
        public static void doWrite_Byte(ushort port, byte aVal)
        {
        }

and also

method_System_Void_RETEND_Kernel_IO_IOPort_DECLEND_doWrite_Byte_NAMEEND__System_UInt16_System_Byte_:
push dword ebp
mov dword ebp, esp
mov dword edx, [ebp+12]
mov dword eax, [ebp+8]
out dx, al
pop dword ebp
ret

Microsoft specific, C compiler directive

(could be compiled into a native object, and then linked into the native kernel, I guess).

void __outbyte(
   unsigned short Port,
   unsigned char Data
);

https://learn.microsoft.com/en-us/cpp/intrinsics/outbyte?view=msvc-160

@AnErrupTion
Copy link

@FrankRay78 How would you plan on adding a custom plug architecture to NativeAOT? That requires hijacking the compiler, and I'm not sure if it's possible.

@FrankRay78
Copy link
Owner Author

How would you plan on adding a custom plug architecture to NativeAOT?

@AnErrupTion I've been thinking about this a lot, and at the moment, I'm favouring an architecture-specific library written in C/C++ with the required methods and inline assembly that I can compile and then somehow link the kernel with.

@AnErrupTion
Copy link

I'm favouring an architecture-specific library written in C/C++ with the required methods and inline assembly that I can compile and then somehow link the kernel with.

So essentially the way MOOS did it with its NativeLib?

@FrankRay78
Copy link
Owner Author

Thanks, I hadn't seen this before: https://github.com/nifanfa/MOOS/blob/master/NativeLib/io.cpp Yes, I was thinking exactly like this.

@FrankRay78
Copy link
Owner Author

I'm having difficulty writing to an IO port from assembly, as being discussed here: io port 0x80 - usage for debugging during OS development. I need to resolve this first, before attempting to call similar from within the C# kernel.

@FrankRay78 FrankRay78 self-assigned this Apr 29, 2024
@FrankRay78
Copy link
Owner Author

I'm not sure if I'm going to use the nativelib approach MOOS takes, as it seems that C# .Net does not support direct linking of an an AOT compiled object file to another native object file. Instead, .Net uses the DllImport attribute as a primary way to call into unmanaged code, for example:

using System;
using System.Runtime.InteropServices;

// Declare the method signature
[DllImport("addThree.dll")]
static extern int addThree(int number);

Console.WriteLine($"addThree(5) = { addThree(5) }");

If I take this approach, then I need to explicitly implement the DllImport attribute the compiler requires eg: https://github.com/nifanfa/MOOS/blob/master/Corlib/System/Runtime/InteropServices/DllImportAttribute.cs

And also implement a host of accompanying InteropHelpers eg:
https://github.com/nifanfa/MOOS/blob/master/Corlib/Internal/Runtime/CompilerHelpers/InteropHelpers.cs
https://github.com/nifanfa/MOOS/blob/master/Corlib/System/EETypePtr.cs

However, without this, I'm not sure there is any other way except for the plug (see above) approach COSMOS/FlingOS took.

@FrankRay78
Copy link
Owner Author

FrankRay78 commented May 16, 2024

I wonder if a modified fork of the ILCompiler might be the way to go?
https://github.com/dotnet/runtime/tree/main/src/coreclr/tools/aot

@FrankRay78
Copy link
Owner Author

@AnErrupTion FYI. I'm continuing my OS development here for the time being: https://github.com/FrankRay78/InstructionOS

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants