diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj b/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj
index ece01df5d..9fdd386f8 100644
--- a/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj
+++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj
@@ -6,6 +6,27 @@
..\..\Cosmos.snk
+
+
+ Engine.cs
+
+
+ Engine.cs
+
+
+ Engine.cs
+
+
+ Engine.cs
+
+
+ Engine.cs
+
+
+ Engine.cs
+
+
+
diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs
index 86e43ff88..5aca1e30d 100644
--- a/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs
+++ b/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs
@@ -28,7 +28,7 @@ namespace Cosmos.TestRunner.Core
engine.DebugIL2CPU = false;
engine.TraceAssembliesLevel = TraceAssemblies.User;
//engine.EnableStackCorruptionChecks = false;
- engine.KernelPkg = "X86G3";
+ engine.KernelPkg = "X86";
engine.EnableStackCorruptionChecks = true;
engine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions;
diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs
index 40cb3d4b8..659406201 100644
--- a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs
+++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs
@@ -163,6 +163,30 @@ namespace Cosmos.TestRunner.Core
RunObjDump(CosmosPaths.Build, workingDir, kernelFileName, OutputHandler.LogError, OutputHandler.LogMessage);
}
+ private void RunTheRingMaster(string kernelFileName)
+ {
+ var xArgs = new List() { kernelFileName };
+
+ bool xUsingUserKit = false;
+ string xTheRingMasterPath = Path.Combine(FindCosmosRoot(), "source", "TheRingMaster");
+ if (!Directory.Exists(xTheRingMasterPath))
+ {
+ xUsingUserKit = true;
+ xTheRingMasterPath = Path.Combine(GetCosmosUserkitFolder(), "Build", "TheRingMaster");
+ }
+
+ if (xUsingUserKit)
+ {
+ RunProcess("TheRingMaster.exe", xTheRingMasterPath, xArgs);
+ }
+ else
+ {
+ xArgs.Insert(0, "run");
+ xArgs.Insert(1, "--no-build");
+ RunProcess("dotnet", xTheRingMasterPath, xArgs);
+ }
+ }
+
private void RunIL2CPU(string kernelFileName, string outputFile)
{
References = new List() { kernelFileName };
@@ -227,8 +251,8 @@ namespace Cosmos.TestRunner.Core
else
{
xArgs.Insert(0, "run");
- xArgs.Insert(3, "--no-build");
- xArgs.Insert(4, " -- ");
+ xArgs.Insert(1, "--no-build");
+ xArgs.Insert(2, " -- ");
RunProcess("dotnet", xIL2CPUPath, xArgs, true);
}
}
diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs
index 08611bd9a..b3881310c 100644
--- a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs
+++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs
@@ -20,6 +20,10 @@ namespace Cosmos.TestRunner.Core
var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o");
var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso");
+ if (KernelPkg == "X86")
+ {
+ RunTask("TheRingMaster", () => RunTheRingMaster(assemblyFileName));
+ }
RunTask("IL2CPU", () => RunIL2CPU(assemblyFileName, xAssemblyFile));
RunTask("Nasm", () => RunNasm(xAssemblyFile, xObjectFile, configuration.IsELF));
if (configuration.IsELF)
diff --git a/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj b/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj
index cfc09c67f..400e445aa 100644
--- a/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj
+++ b/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj
@@ -11,6 +11,7 @@
+
diff --git a/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets b/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets
index fb7964650..0879d43ca 100644
--- a/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets
+++ b/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets
@@ -1,12 +1,12 @@
-
+
False
True
False
true
-
+
$(AppData)\Cosmos User Kit
$(CosmosDir)\Build\Tools
@@ -44,7 +44,7 @@
-
+
@@ -54,8 +54,15 @@
+
+
+
@@ -75,7 +82,7 @@
-
+
-
+
diff --git a/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs b/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs
index cb715b778..2ed18e891 100644
--- a/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs
+++ b/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs
@@ -2,14 +2,13 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Reflection;
using Microsoft.Build.Framework;
using Cosmos.Build.Common;
namespace Cosmos.Build.MSBuild
{
- public class RingCheck : BaseToolTask
+ public class TheRingMaster : BaseToolTask
{
[Required]
public string KernelAssemblyPath { get; set; }
@@ -21,7 +20,19 @@ namespace Cosmos.Build.MSBuild
public override bool Execute()
{
- return ExecuteTool(WorkingDir, Path.Combine(CosmosPaths.Build, "RingCheck", "RingCheck.exe"), KernelAssemblyPath, "Ring Check");
+ var xSW = Stopwatch.StartNew();
+
+ try
+ {
+ Log.LogMessage(MessageImportance.High, $"Invoking TheRingMaster.exe {KernelAssemblyPath}");
+ return ExecuteTool(WorkingDir, Path.Combine(CosmosPaths.Build, "TheRingMaster", "TheRingMaster.exe"), KernelAssemblyPath, "The Ring Master");
+ }
+ finally
+ {
+ xSW.Stop();
+ Log.LogMessage(MessageImportance.High, $"TheRingMaster invoked with KernelAssemblyPath = '{KernelAssemblyPath}'");
+ Log.LogMessage(MessageImportance.High, "TheRingMaster task took {0}", xSW.Elapsed);
+ }
}
}
}
diff --git a/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj b/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj
index cab278f1e..2f7f6b016 100644
--- a/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj
+++ b/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj
@@ -15,8 +15,4 @@
-
-
-
-
diff --git a/Cosmos/source/TheRingMaster/Program.cs b/Cosmos/source/TheRingMaster/Program.cs
index bb5b52f43..7cc9596fc 100644
--- a/Cosmos/source/TheRingMaster/Program.cs
+++ b/Cosmos/source/TheRingMaster/Program.cs
@@ -1,19 +1,193 @@
using System;
-using System.Text;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Loader;
+
+using Cosmos.Build.Common;
namespace TheRingMaster
{
- class Program
+ public class Program
{
- static void Main(string[] args)
+ static Dictionary RingCache = new Dictionary();
+ static string KernelDir;
+
+ public static void Main(string[] args)
{
if (args.Length != 1)
{
+ Console.WriteLine("ARGS:");
+
+ foreach (var xArg in args)
+ {
+ Console.WriteLine(xArg);
+ }
+
Console.WriteLine("Usage: theringmaster ");
return;
}
- var xKernelAssemblyPath = args[1];
+ var xKernelAssemblyPath = args[0];
+
+ if (!File.Exists(xKernelAssemblyPath))
+ {
+ throw new FileNotFoundException("Kernel Assembly not found! Path: '" + xKernelAssemblyPath + "'");
+ }
+
+ KernelDir = Path.GetDirectoryName(xKernelAssemblyPath);
+ AssemblyLoadContext.Default.Resolving += Default_Resolving;
+
+ var xKernelAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(xKernelAssemblyPath);
+ CheckRings(xKernelAssembly, "Application");
+
+ void CheckRings(Assembly aAssembly, string aRing, string aSourceAssemblyName = null)
+ {
+ RingCache.TryGetValue(aAssembly, out var xRing);
+
+ if (xRing == null)
+ {
+ var xManifestName = aAssembly.GetManifestResourceNames()
+ .Where(n => n == aAssembly.GetName().Name + ".Cosmos.cfg")
+ .SingleOrDefault();
+
+ if (xManifestName != null)
+ {
+ Dictionary xCfg;
+
+ using (var xManifestStream = aAssembly.GetManifestResourceStream(xManifestName))
+ {
+ xCfg = ParseCfg(xManifestStream);
+ }
+
+ if (xCfg == null)
+ {
+ throw new Exception("Invalid Cosmos configuration! Resource name: " + xManifestName);
+ }
+
+ xCfg.TryGetValue("Ring", out xRing);
+
+ if (!new string[] { "CPU", "Platform", "HAL", "System", "Application", /*"Plug",*/ "Debug" }.Contains(xRing))
+ {
+ throw new Exception("Unknown ring! Ring: " + xRing);
+ }
+ }
+
+ if (xRing == null)
+ {
+ xRing = "External";
+ }
+ }
+
+ RingCache.Add(aAssembly, xRing);
+
+ // Check Rings
+
+ bool xValid = false;
+
+ // Same rings
+ // OR
+ // External ring, can be referenced by any ring
+ // OR
+ // One of the assemblies is Debug
+ if (aRing == xRing || xRing == "External" || aRing == "Debug" || xRing == "Debug")
+ {
+ xValid = true;
+ }
+
+ if (!xValid)
+ {
+ switch (aRing)
+ {
+ case "Application" when xRing == "System":
+ case "System" when xRing == "HAL":
+ case "Platform" when xRing == "CPU":
+ case "Platform" when xRing == "HAL":
+ //case "Plug" when xRing == "System":
+ return;
+ }
+ }
+
+ if (!xValid)
+ {
+ var xExceptionMessage = "Invalid rings! Source assembly: " + (aSourceAssemblyName ?? "(no assembly)") +
+ ": Ring " + aRing + "; Referenced assembly: " + aAssembly.GetName().Name +
+ ": Ring " + xRing;
+
+ throw new Exception(xExceptionMessage);
+ }
+
+ foreach (var xReference in aAssembly.GetReferencedAssemblies())
+ {
+ try
+ {
+ CheckRings(AssemblyLoadContext.Default.LoadFromAssemblyName(xReference), xRing, aAssembly.GetName().Name);
+ }
+ catch (FileNotFoundException)
+ {
+ }
+ }
+ }
+ }
+
+ private static Assembly Default_Resolving(AssemblyLoadContext aContext, AssemblyName aAssemblyName)
+ {
+ Assembly xAssembly = null;
+
+ if (ResolveAssemblyForDir(KernelDir, out xAssembly))
+ {
+ return xAssembly;
+ }
+
+ if (ResolveAssemblyForDir(CosmosPaths.Kernel, out xAssembly))
+ {
+ return xAssembly;
+ }
+
+ return xAssembly;
+
+ bool ResolveAssemblyForDir(string aDir, out Assembly aAssembly)
+ {
+ aAssembly = null;
+
+ var xFiles = Directory.GetFiles(aDir, aAssemblyName.Name + ".*", SearchOption.TopDirectoryOnly);
+
+ if (xFiles.Any(f => Path.GetExtension(f) == ".dll"))
+ {
+ aAssembly = aContext.LoadFromAssemblyPath(xFiles.Where(f => Path.GetExtension(f) == ".dll").Single());
+ }
+
+ if (xFiles.Any(f => Path.GetExtension(f) == ".exe"))
+ {
+ aAssembly = aContext.LoadFromAssemblyPath(xFiles.Where(f => Path.GetExtension(f) == ".exe").Single());
+ }
+
+ return aAssembly != null;
+ }
+ }
+
+ static Dictionary ParseCfg(Stream aStream)
+ {
+ var xCfg = new Dictionary();
+
+ using (var xReader = new StreamReader(aStream))
+ {
+ while (xReader.Peek() >= 0)
+ {
+ var xLine = xReader.ReadLine();
+
+ if (!xLine.Contains(':') || xLine.Count(c => c == ':') > 1)
+ {
+ return null;
+ }
+
+ var xProperty = xLine.Split(':');
+ xCfg.Add(xProperty[0].Trim(), xProperty[1].Trim());
+ }
+ }
+
+ return xCfg;
}
}
}
diff --git a/Cosmos/source/TheRingMaster/TheRingMaster.csproj b/Cosmos/source/TheRingMaster/TheRingMaster.csproj
index d9499d41a..6c9fd7dce 100644
--- a/Cosmos/source/TheRingMaster/TheRingMaster.csproj
+++ b/Cosmos/source/TheRingMaster/TheRingMaster.csproj
@@ -2,6 +2,15 @@
netcoreapp1.0
+ Exe
+
+
+
+
+
+
+
+