public static void Tests() { var ar = new KList <uint>(); ar.Add(44); ar.Add(55); KernelMessage.WriteLine("CNT: {0}", ManagedMemoy.AllocationCount); foreach (var num in ar) { KernelMessage.WriteLine("VAL: {0}", num); } KernelMessage.WriteLine("CNT: {0}", ManagedMemoy.AllocationCount); ar.Destroy(); KernelMessage.WriteLine("Phys Pages free: {0}", PhysicalPageManager.FreePages); for (var i = 0; i < 10000; i++) { var s = new int[] { 1, 2, 3, 4, }; s[1] = 5; Memory.FreeObject(s); } KernelMessage.WriteLine("Phys Pages free: {0}", PhysicalPageManager.FreePages); //Memory.FreeObject(s); }
private static void Thread1() { KernelMessage.WriteLine("Thread1: Enter"); uint tsLast = 0; //var chars = new char[] { '-', '/', '|', '\\' }; var chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; var charIdx = 0; while (true) { Scheduler.Sleep(0); var ts = PerformanceCounter.GetReadableCounter(); if (ts - tsLast < 1000) { continue; } Screen.SetChar(chars[charIdx], 0, 32, ConsoleColor.White, ConsoleColor.Green); charIdx++; if (charIdx >= chars.Length) { charIdx = 0; } //PhysicalPageManager.DumpPages(); //PhysicalPageManager.DumpStats(); //VirtualPageManager.DumpStats(); tsLast = ts; } KernelMessage.WriteLine("Thread1: Finished"); }
private static void Thread2() { KernelMessage.WriteLine("Thread2: Enter"); uint tsLast = 0; //var chars = new char[] { '-', '/', '|', '\\' }; var chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; var charIdx = 0; var i = 0; while (true) { Scheduler.Sleep(0); var ts = PerformanceCounter.GetReadableCounter(); if (ts - tsLast < 1000) { continue; } Screen.SetChar(chars[charIdx], 0, 34, ConsoleColor.White, ConsoleColor.Red); charIdx++; if (charIdx >= chars.Length) { charIdx = 0; } tsLast = ts; if (i++ > 10) { break; } } KernelMessage.WriteLine("Thread2: Finished"); //while (true) // i++; }
public static void AppMain() { KernelMessage.WriteLine("Kernel ready"); // We have nothing to do (yet). So let's stop. Debug.Break(); }
private static void AppMain() { KernelMessage.WriteLine("Kernel ready"); ThreadTests.TriggerTestPassed(); // We have nothing to do (yet). So let's stop. Debug.Break(); }
private static unsafe void Ulongtest2() { ulong addr = 0x0000000019ad000; ulong data = 40004005; ulong result = data.SetBits(12, 52, addr, 12); var rAddr = (uint *)(void *)&result; var r1 = rAddr[0]; var r2 = rAddr[1]; KernelMessage.WriteLine("r1: {0:X8}", r1); KernelMessage.WriteLine("r2: {0:X8}", r2); }
// public unsafe static void InitialKernelProtect() // { // KernelMessage.WriteLine("Protecting Memory..."); // // PageDirectoryEntry* pde = (PageDirectoryEntry*)AddrPageDirectory; // // for (int index = 0; index < 1024; index++) // // { // // pde[index].Writable = false; // // } // // PageTable.PageTableEntry* pte = (PageTable.PageTableEntry*)PageTable.AddrPageTable; // // for (int index = 0; index < 1024 * 32; index++) // // pte[index].Writable = false; // // InitialKernelProtect_MakeWritable_ByRegion(0, 90 * 1024 * 1024); // KernelMessage.WriteLine("Reload CR3 to {0:X8}", PageTable.AddrPageDirectory); // Native.SetCR3(PageTable.AddrPageDirectory); // //Native.Invlpg(); // KernelMessage.WriteLine("Protecting Memory done"); // } // public unsafe static void InitialKernelProtect_MakeWritable_ByRegion(uint startVirtAddr, uint endVirtAddr) // { // InitialKernelProtect_MakeWritable_BySize(startVirtAddr, endVirtAddr - startVirtAddr); // } // public unsafe static void InitialKernelProtect_MakeWritable_BySize(uint virtAddr, uint size) // { // var pages = KMath.DivCeil(size, 4096); // for (var i = 0; i < pages; i++) // { // var entry = PageTable.GetTableEntry(virtAddr); // entry->Writable = true; // } // } private static void Ulongtest1() { uint mask = 0x00004000; uint v1 = 0x00000007; uint r1 = v1.SetBits(12, 52, mask, 12); //52 with uint makes no sense, but this doesn't matter in this case, the result just works as expected. It works correct with count<32, too, of course. // r1 = 00004007 ulong v2 = v1; ulong r2 = v2.SetBits(12, 52, mask, 12); uint r2Int = (uint)r2; // r2Int = 00000007. This is wrong. It should be the same as r1. KernelMessage.WriteLine("bla1: {0:X8}", r1); KernelMessage.WriteLine("bla2: {0:X8}", r2Int); }
public static void ApplyMode(uint mode) { // https://de.wikibooks.org/wiki/Interrupts_80x86/_INT_10#Funktion_00h:_Setze_Bildschirmmodus_(EGA/VGA) KernelMessage.WriteLine("Screen VBE Mode: {0}", mode); switch (mode) { case 1: Rows = 25; Columns = 40; break; case 3: Rows = 25; Columns = 80; break; } }
public static void SetupUserMode(Addr tssAddr) { KernelMessage.WriteLine("Setup GDT UserMode"); if (KConfig.UseTaskStateSegment) { TssAddr = tssAddr; TssTable = (TaskStateSegmentTable *)tssAddr; TssTable->Clear(); TssTable->AdressOfEntries = TssAddr + TaskStateSegmentTable.StructSize; } if (KConfig.UseTaskStateSegment) { // 9 - TSS Tss = AddTSS(); //tss->esp0 = kernelStackPointer; Tss->SS0 = 0x10; Tss->Trace_bitmap = 0xdfff; KernelMessage.WriteLine("Addr of tss: {0:X8}", (uint)Tss); var tssEntry = DescriptorTableEntry.CreateTSS(Tss); tssEntry.PriviligeRing = 0; tssEntry.TSS_AVL = true; tssEntry.Present = true; GdtTable->AddEntry(tssEntry); } Flush(); if (KConfig.UseTaskStateSegment) { KernelMessage.WriteLine("LoadTaskRegister..."); //LoadTaskRegister(); //Debug, for breakpoint //clockTicks++; //DebugFunction1(); } KernelMessage.WriteLine("Done"); }
/// <summary> /// Sets up the GDT table and entries /// </summary> public static void Setup(Addr addr) { KernelMessage.Write("Setup GDT..."); GdtTableAddress = addr; GdtTable = (DescriptorTable *)GdtTableAddress; GdtTable->Clear(); GdtTable->AdressOfEntries = GdtTableAddress + DescriptorTable.StructSize; //Null segment var nullEntry = DescriptorTableEntry.CreateNullDescriptor(); GdtTable->AddEntry(nullEntry); //code segment var codeEntry = DescriptorTableEntry.CreateCode(0, 0xFFFFFFFF); codeEntry.CodeSegment_Readable = true; codeEntry.PriviligeRing = 0; codeEntry.Present = true; codeEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; //codeEntry.CodeSegment_Confirming = true; GdtTable->AddEntry(codeEntry); //data segment var dataEntry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); dataEntry.DataSegment_Writable = true; dataEntry.PriviligeRing = 0; dataEntry.Present = true; dataEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(dataEntry); Flush(); KernelMessage.WriteLine("Done"); }
public static void SetupUserMode(Addr tssAddr) { KernelMessage.WriteLine("Setup GDT UserMode"); if (KConfig.UseTaskStateSegment) { TssAddr = tssAddr; TssTable = (TaskStateSegmentTable *)tssAddr; TssTable->Clear(); TssTable->AdressOfEntries = TssAddr + TaskStateSegmentTable.StructSize; } //code segment var codeEntry = DescriptorTableEntry.CreateCode(0, 0xFFFFFFFF); codeEntry.CodeSegment_Readable = true; codeEntry.PriviligeRing = 3; codeEntry.Present = true; codeEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; codeEntry.CodeSegment_Confirming = false; GdtTable->AddEntry(codeEntry); //data segment var dataEntry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); dataEntry.DataSegment_Writable = true; dataEntry.PriviligeRing = 3; dataEntry.Present = true; dataEntry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(dataEntry); if (KConfig.UseTaskStateSegment) { //TSS Tss = AddTSS(); //tss->esp0 = kernelStackPointer; Tss->SS0 = 0x10; Tss->Trace_bitmap = 0xdfff; KernelMessage.WriteLine("Addr of tss: {0:X8}", (uint)Tss); var tssEntry = DescriptorTableEntry.CreateTSS(Tss); tssEntry.PriviligeRing = 0; tssEntry.TSS_AVL = true; tssEntry.Present = true; GdtTable->AddEntry(tssEntry); } Flush(); if (KConfig.UseTaskStateSegment) { KernelMessage.WriteLine("LoadTaskRegister..."); //LoadTaskRegister(); //Debug, for breakpoint //clockTicks++; //DebugFunction1(); } KernelMessage.WriteLine("Done"); }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="stackStatePointer">The stack state pointer.</param> private static unsafe void ProcessInterrupt(uint stackStatePointer) { ushort dataSelector = 0x10; Native.SetSegments(dataSelector, dataSelector, dataSelector, dataSelector, dataSelector); var block = (InterruptControlBlock *)Address.InterruptControlBlock; Native.SetCR3(block->KernelPageTableAddr); //KernelMessage.WriteLine("Interrupt occurred"); var stack = (IDTStack *)stackStatePointer; var irq = stack->Interrupt; uint pageTableAddr = 0; var thread = Scheduler.GetCurrentThread(); if (thread != null) { dataSelector = (ushort)thread.DataSelector; pageTableAddr = thread.Process.PageTable.GetPageTablePhysAddr(); } if (!IDTManager.Enabled) { PIC.SendEndOfInterrupt(irq); return; } var interruptInfo = IDTManager.Handlers[irq]; if (KConfig.Log.Interrupts && interruptInfo.Trace && thread != null) { KernelMessage.WriteLine("Interrupt {0}, Thread {1}, EIP={2:X8} ESP={3:X8}", irq, thread.ThreadID, stack->EIP, stack->ESP); } IDTManager.RaisedCount++; if (interruptInfo.CountStatistcs) { IDTManager.RaisedCountCustom++; } if (KConfig.Log.Interrupts) { if (interruptInfo.Trace) { KernelMessage.WriteLine("Interrupt: {0}", irq); } var col = Screen.Column; var row = Screen.Row; Screen.Column = 0; Screen.Goto(2, 35); Screen.Write("Interrupts: "); Screen.Write(IDTManager.RaisedCount); Screen.Goto(3, 35); Screen.Write("IntNoClock: "); Screen.Write(IDTManager.RaisedCountCustom); Screen.Row = row; Screen.Column = col; } if (irq < 0 || irq > 255) { Panic.Error("Invalid Interrupt"); } if (interruptInfo.PreHandler != null) { interruptInfo.PreHandler(stack); } if (interruptInfo.Handler == null) { Panic.Error("Handler is null"); } else { } interruptInfo.Handler(stack); PIC.SendEndOfInterrupt(irq); if (pageTableAddr > 0) { Native.SetCR3(pageTableAddr); } Native.SetSegments(dataSelector, dataSelector, dataSelector, dataSelector, 0x10); }
public static unsafe void Main() { try { ManagedMemoy.InitializeGCMemory(); StartUp.InitializeAssembly(); KMath.Init(); //Mosa.Runtime.StartUp.InitializeRuntimeMetadata(); BootInfo.SetupStage1(); Memory.InitialKernelProtect(); ApiContext.Current = new ApiHost(); Assert.Setup(AssertError); // Setup some pseudo devices DeviceManager.InitStage1(); //Setup Output and Debug devices DeviceManager.InitStage2(); // Write first output KernelMessage.WriteLine("<KERNEL:CONSOLE:BEGIN>"); PerformanceCounter.Setup(BootInfo.Header->KernelBootStartCycles); KernelMessage.WriteLine("Starting Abanu Kernel..."); KernelMessage.WriteLine("KConfig.UseKernelMemoryProtection: {0}", KConfig.UseKernelMemoryProtection); KernelMessage.WriteLine("KConfig.UsePAE: {0}", KConfig.UsePAE); KernelMessage.WriteLine("Apply PageTableType: {0}", (uint)BootInfo.Header->PageTableType); KernelMessage.WriteLine("GCInitialMemory: {0:X8}-{1:X8}", Address.GCInitialMemory, Address.GCInitialMemory + Address.GCInitialMemorySize - 1); Ulongtest1(); Ulongtest2(); InlineTest(); // Detect environment (Memory Maps, Video Mode, etc.) BootInfo.SetupStage2(); KernelMemoryMapManager.Setup(); //KernelMemoryMapManager.Allocate(0x1000 * 1000, BootInfoMemoryType.PageDirectory); // Read own ELF-Headers and Sections KernelElf.Setup(); // Initialize the embedded code (actually only a little proof of concept code) NativeCalls.Setup(); //InitialKernelProtect(); PhysicalPageManager.Setup(); KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); PhysicalPageManager.AllocatePages(10); KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); VirtualPageManager.Setup(); Memory.Setup(); // Now Memory Sub System is working. At this point it's valid // to allocate memory dynamically DeviceManager.InitFrameBuffer(); // Setup Programmable Interrupt Table PIC.Setup(); // Setup Interrupt Descriptor Table // Important Note: IDT depends on GDT. Never setup IDT before GDT. IDTManager.Setup(); InitializeUserMode(); SysCallManager.Setup(); KernelMessage.WriteLine("Initialize Runtime Metadata"); StartUp.InitializeRuntimeMetadata(); KernelMessage.WriteLine("Performing some Non-Thread Tests"); Tests(); } catch (Exception ex) { Panic.Error(ex.Message); } if (KConfig.SingleThread) { StartupStage2(); } else { ProcessManager.Setup(StartupStage2); } }
public static unsafe void StartupStage2() { try { if (!KConfig.SingleThread) { Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(BackgroundWorker.ThreadMain) { DebugName = "BackgroundWorker", Priority = -5 }).Start(); Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(Thread0) { DebugName = "KernelThread0", Priority = -5 }).Start(); var userProc = ProcessManager.CreateEmptyProcess(new ProcessCreateOptions { User = false }); userProc.Path = "/buildin/testproc"; Scheduler.CreateThread(userProc, new ThreadStartOptions(Thread1) { AllowUserModeIOPort = true, DebugName = "UserThread1", Priority = -5 }); Scheduler.CreateThread(userProc, new ThreadStartOptions(Thread2) { AllowUserModeIOPort = true, DebugName = "UserThread2", Priority = -5 }); userProc.Start(); var fileProc = ProcessManager.StartProcess("Service.Basic"); FileServ = fileProc.Service; KernelMessage.WriteLine("Waiting for Service"); while (FileServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("Service Ready"); //var buf = Abanu.Runtime.SysCalls.RequestMessageBuffer(4096, FileServ.Process.ProcessID); //var kb = Abanu.Runtime.SysCalls.OpenFile(buf, "/dev/keyboard"); //KernelMessage.Write("kb Handle: {0:X8}", kb); //buf.Size = 4; //Abanu.Runtime.SysCalls.WriteFile(kb, buf); //Abanu.Runtime.SysCalls.ReadFile(kb, buf); //var procHostCommunication = ProcessManager.StartProcess("Service.HostCommunication"); //ServHostCommunication = new Service(procHostCommunication); //// TODO: Optimize Registration //SysCallManager.SetCommandProcess(SysCallTarget.HostCommunication_CreateProcess, procHostCommunication); var proc = ProcessManager.StartProcess("App.HelloService"); Serv = proc.Service; var p2 = ProcessManager.StartProcess("App.HelloKernel"); //p2.Threads[0].SetArgument(0, 0x90); //p2.Threads[0].SetArgument(4, 0x94); //p2.Threads[0].SetArgument(8, 0x98); p2.Threads[0].Debug = true; var p3 = ProcessManager.StartProcess("App.Shell"); ProcessManager.System.Threads[0].Status = ThreadStatus.Terminated; } VirtualPageManager.SetTraceOptions(new PageFrameAllocatorTraceOptions { Enabled = true, MinPages = 1 }); KernelMessage.WriteLine("Enter Main Loop"); AppMain(); } catch (Exception ex) { Panic.Error(ex.Message); } }
public static unsafe void TestPhysicalPageAllocation() { KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); PhysicalPageManager.AllocatePages(10); KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); }
/// <summary> /// Entry point into the ISR (Interrupt Service Routine) /// </summary> /// <param name="stack">Pointer to the ISR stack</param> private static unsafe void ProcessInterrupt(ref IDTStack stack) { // Switch to Kernel segments ushort dataSelector = KnownSegments.KernelData; Native.SetSegments(dataSelector, dataSelector, KnownSegments.KernelThreadStorage, dataSelector, dataSelector); // Switch to Kernel Adresse space var block = (InterruptControlBlock *)Address.InterruptControlBlock; Native.SetCR3(block->KernelPageTableAddr); // Get the IRQ var irq = stack.Interrupt; // Get the pagetable address of the interrupted process uint pageTableAddr = 0; var thread = Scheduler.GetCurrentThread(); if (thread != null) { dataSelector = (ushort)thread.DataSelector; pageTableAddr = thread.Process.PageTable.GetPageTablePhysAddr(); } // If the IDTManager is not initialized yet or hard disabled, we return now if (!IDTManager.Enabled) { PIC.SendEndOfInterrupt(irq); return; } // Get interrupt info for the IRQ var interruptInfo = IDTManager.Handlers[irq]; if (KConfig.Log.Interrupts && interruptInfo.Trace && thread != null) { KernelMessage.WriteLine("Interrupt {0}, Thread {1}, EIP={2:X8} ESP={3:X8}", irq, (uint)thread.ThreadID, stack.EIP, stack.ESP); } // Some statistics IDTManager.RaisedCount++; if (interruptInfo.CountStatistcs) { IDTManager.RaisedCountCustom++; } if (KConfig.Log.Interrupts) { if (interruptInfo.Trace) { KernelMessage.WriteLine("Interrupt: {0}", irq); } var col = Screen.Column; var row = Screen.Row; Screen.Column = 0; Screen.Goto(2, 35); Screen.Write("Interrupts: "); Screen.Write(IDTManager.RaisedCount); Screen.Goto(3, 35); Screen.Write("IntNoClock: "); Screen.Write(IDTManager.RaisedCountCustom); Screen.Row = row; Screen.Column = col; } // This should never happen if (irq < 0 || irq > 255) { Panic.Error("Invalid Interrupt"); } // Invoke handlers if (interruptInfo.PreHandler != null) { interruptInfo.PreHandler(ref stack); } if (interruptInfo.Handler == null) { Panic.Error("Handler is null"); } else { } interruptInfo.Handler(ref stack); // Important! Otherwise we will get any more interrupts of this kind PIC.SendEndOfInterrupt(irq); // Switch to original address space if (pageTableAddr > 0) { Native.SetCR3(pageTableAddr); } // Switch to original segments Native.SetSegments(dataSelector, dataSelector, KnownSegments.UserThreadStorage, dataSelector, KnownSegments.KernelData); // ISR is completed. The upper ISR stub will re-enable interrupts and resume the original process }
private static void StartupStage2() { try { if (!KConfig.SingleThread) { Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(BackgroundWorker.ThreadMain) { DebugName = "BackgroundWorker", Priority = -5 }).Start(); ThreadTests.StartTestThreads(); // Start some applications var fileProc = ProcessManager.CreateProcess("Service.Basic"); FileServ = fileProc.Service; fileProc.Start(); KernelMessage.WriteLine("Waiting for Service"); while (FileServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("Service Ready"); var conProc = ProcessManager.CreateProcess("Service.ConsoleServer"); conProc.Start(); var conServ = conProc.Service; KernelMessage.WriteLine("Waiting for ConsoleServer"); while (conServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("ConsoleServer Ready"); //var buf = Abanu.Runtime.SysCalls.RequestMessageBuffer(4096, FileServ.Process.ProcessID); //var kb = Abanu.Runtime.SysCalls.OpenFile(buf, "/dev/keyboard"); //KernelMessage.Write("kb Handle: {0:X8}", kb); //buf.Size = 4; //Abanu.Runtime.SysCalls.WriteFile(kb, buf); //Abanu.Runtime.SysCalls.ReadFile(kb, buf); //var procHostCommunication = ProcessManager.StartProcess("Service.HostCommunication"); //ServHostCommunication = new Service(procHostCommunication); //// TODO: Optimize Registration //SysCallManager.SetCommandProcess(SysCallTarget.HostCommunication_CreateProcess, procHostCommunication); var proc = ProcessManager.CreateProcess("App.HelloService"); Serv = proc.Service; proc.Start(); var p2 = ProcessManager.CreateProcess("App.HelloKernel"); p2.Start(); //p2.Threads[0].SetArgument(0, 0x90); //p2.Threads[0].SetArgument(4, 0x94); //p2.Threads[0].SetArgument(8, 0x98); p2.Threads[0].Debug = true; var p3 = ProcessManager.CreateProcess("App.Shell"); p3.Start(); ProcessManager.System.Threads[0].Status = ThreadStatus.Terminated; } VirtualPageManager.SetTraceOptions(new PageFrameAllocatorTraceOptions { Enabled = true, MinPages = 1 }); KernelMessage.WriteLine("Enter Main Loop"); AppMain(); } catch (Exception ex) { Panic.Error(ex.Message); } }
/// <summary> /// Sets up the GDT table and entries /// </summary> public static void Setup(Addr addr) { KernelMessage.Write("Setup GDT..."); GdtTableAddress = addr; GdtTable = (DescriptorTable *)GdtTableAddress; GdtTable->Clear(); GdtTable->AdressOfEntries = GdtTableAddress + DescriptorTable.StructSize; // 0 - Null segment var entry = DescriptorTableEntry.CreateNullDescriptor(); GdtTable->AddEntry(entry); // 1 - code segment entry = DescriptorTableEntry.CreateCode(0, 0xFFFFFFFF); entry.CodeSegment_Readable = true; entry.PriviligeRing = 0; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; //codeEntry.CodeSegment_Confirming = true; GdtTable->AddEntry(entry); // 2 - data segment entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 0; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); // 3 - reserved entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 0; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); // 4 - kernel thread storage entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 0; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); // 5 - reserved entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 0; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); // --- // 6 - user code segment entry = DescriptorTableEntry.CreateCode(0, 0xFFFFFFFF); entry.CodeSegment_Readable = true; entry.PriviligeRing = 3; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; entry.CodeSegment_Confirming = false; GdtTable->AddEntry(entry); // 7 - user data segment entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 3; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); // 8 - thread storage segment for FS register entry = DescriptorTableEntry.CreateData(0, 0xFFFFFFFF); entry.DataSegment_Writable = true; entry.PriviligeRing = 3; entry.Present = true; entry.AddressMode = DescriptorTableEntry.EAddressMode.Bits32; GdtTable->AddEntry(entry); Flush(); KernelMessage.WriteLine("Done"); }
/// <summary> /// Signal the Integration tests, that Test was successful. /// </summary> public static void TriggerTestPassed() { Uninterruptible.Execute(() => KernelMessage.WriteLine(KConfig.SelfTestPassedMarker)); }