Merge pull request #1507 from CosmosOS/feature/qemu

Feature/qemu
This commit is contained in:
Charles Betros 2020-10-20 11:55:40 -05:00 committed by GitHub
commit 39b6f889de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 359 additions and 144 deletions

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Cosmos.Build.Common;
using Cosmos.Debug.DebugConnectors;
using Cosmos.Debug.Hosts;
namespace Cosmos.TestRunner.Core
{
partial class Engine
{
private void RunIsoInQemu(string iso, string harddisk, string workingDir)
{
if (!File.Exists(harddisk))
{
throw new FileNotFoundException("Harddisk file not found!", harddisk);
}
var xParams = new Dictionary<string, string>
{
{BuildPropertyNames.IsoFileString, iso}
};
var xDebugConnector = new DebugConnectorPipeClient("Cosmos\\Serial");
InitializeDebugConnector(xDebugConnector);
var xQemu = new Qemu(xParams, RunWithGDB, harddisk)
{
OnShutDown = (a, b) => { mKernelRunning = false; },
RedirectOutput = false,
LogError = s => OutputHandler.LogDebugMessage(s),
LogOutput = s => OutputHandler.LogDebugMessage(s)
};
HandleRunning(xDebugConnector, xQemu);
}
}
}

View file

@ -54,6 +54,9 @@ namespace Cosmos.TestRunner.Core
case RunTargetEnum.Bochs: case RunTargetEnum.Bochs:
RunTask("RunISO", () => RunIsoInBochs(xIsoFile, xHarddiskPath, workingDirectory)); RunTask("RunISO", () => RunIsoInBochs(xIsoFile, xHarddiskPath, workingDirectory));
break; break;
case RunTargetEnum.Qemu:
RunTask("RunISO", () => RunIsoInQemu(xIsoFile, xHarddiskPath, workingDirectory));
break;
case RunTargetEnum.VMware: case RunTargetEnum.VMware:
RunTask("RunISO", () => RunIsoInVMware(xIsoFile, xHarddiskPath)); RunTask("RunISO", () => RunIsoInVMware(xIsoFile, xHarddiskPath));
break; break;

View file

@ -106,7 +106,6 @@ namespace Cosmos.TestRunner.Core
foreach (var xTarget in RunTargets) foreach (var xTarget in RunTargets)
{ {
yield return new RunConfiguration(isElf: true, runTarget: xTarget); yield return new RunConfiguration(isElf: true, runTarget: xTarget);
//yield return new RunConfiguration(isElf: false, runTarget: xTarget);
} }
} }
} }

View file

@ -4,6 +4,7 @@
{ {
Bochs, Bochs,
VMware, VMware,
HyperV HyperV,
Qemu
} }
} }

View file

@ -9,6 +9,11 @@
{ {
IsELF = isElf; IsELF = isElf;
RunTarget = runTarget; RunTarget = runTarget;
if (runTarget == RunTargetEnum.Qemu)
{
IsELF = false;
}
} }
} }
} }

View file

@ -17,6 +17,7 @@ namespace Cosmos.TestRunner.Full
yield return RunTargetEnum.Bochs; yield return RunTargetEnum.Bochs;
//yield return RunTargetEnum.VMware; //yield return RunTargetEnum.VMware;
//yield return RunTargetEnum.HyperV; //yield return RunTargetEnum.HyperV;
//yield return RunTargetEnum.Qemu;
} }
} }

View file

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Cosmos.Build.Common;
namespace Cosmos.Debug.Hosts
{
public class Qemu : Host
{
private static Process qemuProcess;
private string _harddiskFile;
private string _isoFile;
private string _debugPortString;
public bool RedirectOutput = false;
public Action<string> LogOutput;
public Action<string> LogError;
public Qemu(Dictionary<string, string> aParams, bool aUseGDB, string aHarddisk = null)
: base(aParams, aUseGDB)
{
if (String.IsNullOrWhiteSpace(aHarddisk))
{
_harddiskFile = Path.Combine(CosmosPaths.Build, @"VMWare\Workstation\Filesystem.vmdk");
}
else
{
_harddiskFile = aHarddisk;
}
if (aParams.ContainsKey("ISOFile"))
{
_isoFile = aParams["IOSFile"];
}
_debugPortString = "Cosmos\\Serial";
}
public override void Start()
{
qemuProcess = new Process();
var qemuStartInfo = qemuProcess.StartInfo;
qemuStartInfo.FileName = QemuSupport.QemuExe.FullName;
string xQemuArguments = "-m 128";
xQemuArguments += $" -cdrom {_isoFile}";
if (!string.IsNullOrWhiteSpace(_harddiskFile))
{
xQemuArguments += $" -hda {_harddiskFile}";
}
if (!string.IsNullOrWhiteSpace(_debugPortString))
{
xQemuArguments += $" -chardev pipe,path=\\\\Cosmos\\Serial,id=Cosmos -device isa-serial,chardev=Cosmos";
}
xQemuArguments += " -boot d";
qemuStartInfo.Arguments = xQemuArguments;
if (RedirectOutput)
{
if (LogOutput == null)
{
throw new Exception("No LogOutput handler specified!");
}
if (LogError == null)
{
throw new Exception("No LogError handler specified!");
}
}
qemuProcess.EnableRaisingEvents = true;
qemuProcess.Exited += ExitCallback;
qemuProcess.Start();
if (RedirectOutput)
{
qemuProcess.BeginErrorReadLine();
qemuProcess.BeginOutputReadLine();
}
}
private void ExitCallback(object sender, EventArgs e)
{
if (OnShutDown != null)
{
try
{
OnShutDown(sender, e);
}
catch
{
}
}
}
public override void Stop()
{
if (qemuProcess != null)
{
try
{
qemuProcess.Kill();
}
catch
{
}
}
Cleanup();
}
private void Cleanup()
{
OnShutDown(this, null);
qemuProcess.Exited -= ExitCallback;
}
}
}

View file

@ -309,13 +309,11 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
string xPortType = xParts[0].ToLower(); string xPortType = xParts[0].ToLower();
string xPortParam = xParts[1].ToLower(); string xPortParam = xParts[1].ToLower();
var xLaunch = mDebugInfo[BuildPropertyNames.LaunchString];
OutputText("Starting debug connector."); OutputText("Starting debug connector.");
switch (xPortType) switch (xPortType)
{ {
case "pipe:": case "pipe:":
if (xLaunch == "HyperV") if (mLaunch == LaunchType.HyperV || mLaunch == LaunchType.Qemu)
{ {
mDbgConnector = new DebugConnectorPipeClient(xPortParam); mDbgConnector = new DebugConnectorPipeClient(xPortParam);
} }
@ -325,7 +323,7 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
} }
break; break;
case "serial:": case "serial:":
if (xLaunch == "IntelEdison") if (mLaunch == LaunchType.IntelEdison)
{ {
mDbgConnector = new DebugConnectorEdison(xPortParam, Path.ChangeExtension(mDebugInfo["ISOFile"], ".bin")); mDbgConnector = new DebugConnectorEdison(xPortParam, Path.ChangeExtension(mDebugInfo["ISOFile"], ".bin"));
} }
@ -336,7 +334,6 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
break; break;
default: default:
throw new Exception("No debug connector found for port type '" + xPortType + "'"); throw new Exception("No debug connector found for port type '" + xPortType + "'");
} }
mDbgConnector.SetConnectionHandler(DebugConnectorConnected); mDbgConnector.SetConnectionHandler(DebugConnectorConnected);
mDbgConnector.CmdBreak += new Action<uint>(DbgCmdBreak); mDbgConnector.CmdBreak += new Action<uint>(DbgCmdBreak);
@ -560,6 +557,13 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
//((Host.Bochs)mHost).FixBochsConfiguration(new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("IsoFileName", mISO) }); //((Host.Bochs)mHost).FixBochsConfiguration(new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("IsoFileName", mISO) });
break; break;
case LaunchType.Qemu:
if (!QemuSupport.QemuEnabled)
{
throw new Exception("The Qemu emulator doesn't seem to be installed on this machine.");
}
mHost = new Qemu(mDebugInfo, xUseGDB);
break;
case LaunchType.IntelEdison: case LaunchType.IntelEdison:
mHost = new IntelEdison(mDebugInfo, false); mHost = new IntelEdison(mDebugInfo, false);
break; break;

View file

@ -28,6 +28,7 @@
<EnumValue Name="VMware" DisplayName="VMware" /> <EnumValue Name="VMware" DisplayName="VMware" />
<EnumValue Name="Slave" DisplayName="Attached Slave (CanaKit)" /> <EnumValue Name="Slave" DisplayName="Attached Slave (CanaKit)" />
<EnumValue Name="Bochs" DisplayName="Bochs" /> <EnumValue Name="Bochs" DisplayName="Bochs" />
<EnumValue Name="Qemu" DisplayName="Qemu" />
<EnumValue Name="IntelEdison" DisplayName="Intel Edison" /> <EnumValue Name="IntelEdison" DisplayName="Intel Edison" />
<EnumValue Name="HyperV" DisplayName="Hyper-V" /> <EnumValue Name="HyperV" DisplayName="Hyper-V" />
</EnumProperty> </EnumProperty>

View file

@ -82,6 +82,7 @@
this.tabBochs = new System.Windows.Forms.TabPage(); this.tabBochs = new System.Windows.Forms.TabPage();
this.checkStartBochsDebugGui = new System.Windows.Forms.CheckBox(); this.checkStartBochsDebugGui = new System.Windows.Forms.CheckBox();
this.checkEnableBochsDebug = new System.Windows.Forms.CheckBox(); this.checkEnableBochsDebug = new System.Windows.Forms.CheckBox();
this.tabQemu = new System.Windows.Forms.TabPage();
this.tabPXE = new System.Windows.Forms.TabPage(); this.tabPXE = new System.Windows.Forms.TabPage();
this.butnPxeRefresh = new System.Windows.Forms.Button(); this.butnPxeRefresh = new System.Windows.Forms.Button();
this.comboPxeInterface = new System.Windows.Forms.ComboBox(); this.comboPxeInterface = new System.Windows.Forms.ComboBox();
@ -111,6 +112,7 @@
this.tabLaunch.SuspendLayout(); this.tabLaunch.SuspendLayout();
this.tabVMware.SuspendLayout(); this.tabVMware.SuspendLayout();
this.tabBochs.SuspendLayout(); this.tabBochs.SuspendLayout();
this.tabQemu.SuspendLayout();
this.tabPXE.SuspendLayout(); this.tabPXE.SuspendLayout();
this.tabUSB.SuspendLayout(); this.tabUSB.SuspendLayout();
this.tabISO.SuspendLayout(); this.tabISO.SuspendLayout();
@ -156,6 +158,7 @@
this.TabControl1.Controls.Add(this.tabVMware); this.TabControl1.Controls.Add(this.tabVMware);
this.TabControl1.Controls.Add(this.tabHyperV); this.TabControl1.Controls.Add(this.tabHyperV);
this.TabControl1.Controls.Add(this.tabBochs); this.TabControl1.Controls.Add(this.tabBochs);
this.TabControl1.Controls.Add(this.tabQemu);
this.TabControl1.Controls.Add(this.tabPXE); this.TabControl1.Controls.Add(this.tabPXE);
this.TabControl1.Controls.Add(this.tabUSB); this.TabControl1.Controls.Add(this.tabUSB);
this.TabControl1.Controls.Add(this.tabISO); this.TabControl1.Controls.Add(this.tabISO);
@ -704,6 +707,16 @@
this.checkEnableBochsDebug.Text = "Enable Bochs Debugger"; this.checkEnableBochsDebug.Text = "Enable Bochs Debugger";
this.checkEnableBochsDebug.UseVisualStyleBackColor = true; this.checkEnableBochsDebug.UseVisualStyleBackColor = true;
// //
// tabQemu
//
this.tabQemu.Location = new System.Drawing.Point(4, 22);
this.tabQemu.Name = "tabQemu";
this.tabQemu.Padding = new System.Windows.Forms.Padding(3);
this.tabQemu.Size = new System.Drawing.Size(627, 486);
this.tabQemu.TabIndex = 5;
this.tabQemu.Text = "Qemu";
this.tabQemu.UseVisualStyleBackColor = true;
//
// tabPXE // tabPXE
// //
this.tabPXE.Controls.Add(this.butnPxeRefresh); this.tabPXE.Controls.Add(this.butnPxeRefresh);
@ -865,6 +878,7 @@
this.tabVMware.ResumeLayout(false); this.tabVMware.ResumeLayout(false);
this.tabVMware.PerformLayout(); this.tabVMware.PerformLayout();
this.tabBochs.ResumeLayout(false); this.tabBochs.ResumeLayout(false);
this.tabQemu.ResumeLayout(false);
this.tabPXE.ResumeLayout(false); this.tabPXE.ResumeLayout(false);
this.tabPXE.PerformLayout(); this.tabPXE.PerformLayout();
this.tabUSB.ResumeLayout(false); this.tabUSB.ResumeLayout(false);
@ -909,6 +923,7 @@
private System.Windows.Forms.CheckBox checkIgnoreDebugStubAttribute; private System.Windows.Forms.CheckBox checkIgnoreDebugStubAttribute;
private System.Windows.Forms.TabPage tabBochs; private System.Windows.Forms.TabPage tabBochs;
private System.Windows.Forms.CheckBox checkEnableBochsDebug; private System.Windows.Forms.CheckBox checkEnableBochsDebug;
private System.Windows.Forms.TabPage tabQemu;
private System.Windows.Forms.TabPage tabVMware; private System.Windows.Forms.TabPage tabVMware;
private System.Windows.Forms.CheckBox checkEnableGDB; private System.Windows.Forms.CheckBox checkEnableGDB;
private System.Windows.Forms.CheckBox checkStartCosmosGDB; private System.Windows.Forms.CheckBox checkStartCosmosGDB;

View file

@ -36,6 +36,7 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
protected int mHyperVDebugPipe; protected int mHyperVDebugPipe;
protected bool mShowTabBochs; protected bool mShowTabBochs;
protected bool mShowTabQemu;
protected bool mShowTabDebug; protected bool mShowTabDebug;
protected bool mShowTabDeployment; protected bool mShowTabDeployment;
protected bool mShowTabLaunch; protected bool mShowTabLaunch;
@ -98,8 +99,8 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
if (xValue != mViewModel.BuildProperties.Launch) if (xValue != mViewModel.BuildProperties.Launch)
{ {
mViewModel.BuildProperties.Launch = xValue; mViewModel.BuildProperties.Launch = xValue;
// Bochs requires an ISO. Force Deployment property. // Bochs and Qemu requires an ISO. Force Deployment property.
if (LaunchType.Bochs == xValue) if (xValue == LaunchType.Bochs)
{ {
if (DeploymentType.ISO != mViewModel.BuildProperties.Deployment) if (DeploymentType.ISO != mViewModel.BuildProperties.Deployment)
{ {
@ -329,6 +330,7 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
RemoveTab(tabISO); RemoveTab(tabISO);
RemoveTab(tabSlave); RemoveTab(tabSlave);
RemoveTab(tabBochs); RemoveTab(tabBochs);
RemoveTab(tabQemu);
if (mShowTabDebug) if (mShowTabDebug)
{ {
@ -372,6 +374,10 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
{ {
TabControl1.TabPages.Add(tabBochs); TabControl1.TabPages.Add(tabBochs);
} }
if (mShowTabQemu)
{
TabControl1.TabPages.Add(tabQemu);
}
if (TabControl1.TabPages.Contains(xTab)) if (TabControl1.TabPages.Contains(xTab))
{ {
@ -435,6 +441,15 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
cmboVisualStudioDebugPort.Enabled = false; cmboVisualStudioDebugPort.Enabled = false;
cmboVisualStudioDebugPort.SelectedIndex = mVMwareAndBochsDebugPipe; cmboVisualStudioDebugPort.SelectedIndex = mVMwareAndBochsDebugPipe;
} }
else if (mViewModel.BuildProperties.Profile == "Qemu")
{
mShowTabQemu = true;
chckEnableDebugStub.Checked = true;
chkEnableStackCorruptionDetection.Checked = true;
cmboCosmosDebugPort.Enabled = false;
cmboVisualStudioDebugPort.Enabled = false;
cmboVisualStudioDebugPort.SelectedIndex = mVMwareAndBochsDebugPipe;
}
else if (mViewModel.BuildProperties.Profile == "IntelEdison") else if (mViewModel.BuildProperties.Profile == "IntelEdison")
{ {
mShowTabBochs = false; mShowTabBochs = false;
@ -513,7 +528,8 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
mShowTabVMware = mViewModel.BuildProperties.Launch == LaunchType.VMware; mShowTabVMware = mViewModel.BuildProperties.Launch == LaunchType.VMware;
mShowTabHyperV = mViewModel.BuildProperties.Launch == LaunchType.HyperV; mShowTabHyperV = mViewModel.BuildProperties.Launch == LaunchType.HyperV;
mShowTabSlave = mViewModel.BuildProperties.Launch == LaunchType.Slave; mShowTabSlave = mViewModel.BuildProperties.Launch == LaunchType.Slave;
mShowTabBochs = (LaunchType.Bochs == mViewModel.BuildProperties.Launch); mShowTabBochs = mViewModel.BuildProperties.Launch == LaunchType.Bochs;
mShowTabQemu = mViewModel.BuildProperties.Launch == LaunchType.Qemu;
// //
UpdateTabs(); UpdateTabs();
} }

View file

@ -15,6 +15,10 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
{ {
Add("Bochs", "Bochs"); Add("Bochs", "Bochs");
} }
if (QemuSupport.QemuEnabled)
{
Add("Qemu", "Qemu");
}
Add("IntelEdison", "Intel Edison Serial boot"); Add("IntelEdison", "Intel Edison Serial boot");
Add("HyperV", "Hyper-V"); Add("HyperV", "Hyper-V");
} }