mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
Limitations :
- Bochs must be installed on the system. This is not checked as a prerequisite by the Builder.
- You will find a GuessForBochs Cosmos project under BlueSkeye user project folder that can be used to launch the Guess project under Bochs.
- You may have to fix manually the path for the following properties in Cosmos.bxrc file copied to the CosmosForBochs\Bin\Debug folder
* romimage
* vgaromimage
- The Cosmos project UI is not yet Bochs aware. If you do not use the GuessForBochs project you must manually edit your Cosmos project file to modify the following property in both the Debug and Release property group from the project file :
<Launch>Bochs</Launch>
You must also add the following properties in both the Debug and Release property group from the project file :
<BochsConfig>Cosmos.bxrc</BochsConfig>
<Bochs_Deployment>ISO</Bochs_Deployment>
<Bochs_Launch>Bochs</Bochs_Launch>
<Bochs_DebugEnabled>True</Bochs_DebugEnabled>
<Bochs_DebugMode>Source</Bochs_DebugMode>
<Bochs_IgnoreDebugStubAttribute />
<Bochs_VMwareEdition>Player</Bochs_VMwareEdition>
<Bochs_OutputPath>bin\Debug\</Bochs_OutputPath>
<Bochs_Framework>MicrosoftNET</Bochs_Framework>
<Bochs_UseInternalAssembler>False</Bochs_UseInternalAssembler>
<Bochs_TraceAssemblies />
<Bochs_EnableGDB>False</Bochs_EnableGDB>
<Bochs_StartCosmosGDB>false</Bochs_StartCosmosGDB>
<Bochs_Name>GuessForBochs</Bochs_Name>
<Bochs_Description>Use Bochs emulator to deploy and debug.</Bochs_Description>
<Bochs_VisualStudioDebugPort>Pipe: Cosmos\Serial</Bochs_VisualStudioDebugPort>
<Bochs_PxeInterface>192.168.43.1</Bochs_PxeInterface>
<Bochs_SlavePort>Serial: COM3</Bochs_SlavePort>
<Bochs_ShowLaunchConsole>False</Bochs_ShowLaunchConsole>
152 lines
5.2 KiB
C#
152 lines
5.2 KiB
C#
// DO NOT remove the following line. Should you want to get rid of read count tracking comment
|
|
// out the line. Enabling the symbol will handle a thread safe counter that tracks the count
|
|
// of pending reads on the link to the DebugStub.
|
|
// #define TRACK_PENDING
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace Cosmos.Debug.Common {
|
|
/// <summary>Use a Stream to implement wire transfer protocol between a Debug Stub hosted in
|
|
/// a debugged Cosmos Kernel and our Debug Engine hosted in Visual Studio. This class is still
|
|
/// abstract and is further refined by sub-classes handling serial communication line or pipe
|
|
/// for example.</summary>
|
|
public abstract class DebugConnectorStream : DebugConnector {
|
|
#if TRACK_PENDING
|
|
/// <summary>For debugging purpose we track the number of pending read operations. Should this
|
|
/// counter fail to 0, the connector should be considered stalled.</summary>
|
|
private int _pendingReadsCount = 0;
|
|
#endif
|
|
private Stream mStream;
|
|
|
|
protected class Incoming {
|
|
public Stream Stream;
|
|
// Buffer to hold incoming message
|
|
public byte[] Packet;
|
|
// Current # of bytes in mPacket
|
|
public int CurrentPos = 0;
|
|
public Action<byte[]> Completed;
|
|
}
|
|
|
|
private static string BytesToString(byte[] bytes, int index, int count) {
|
|
if (count > 100) {
|
|
return String.Empty;
|
|
}
|
|
var xSB = new StringBuilder(2 + (bytes.Length * 2));
|
|
xSB.Append("0x");
|
|
for (int i = index; i < index + count; i++) {
|
|
xSB.Append(bytes[i].ToString("X2").ToString());
|
|
}
|
|
return xSB.ToString();
|
|
}
|
|
|
|
protected override void SendRawData(byte[] aBytes) {
|
|
System.Diagnostics.Debug.WriteLine(String.Format("DC - sending: {0}", BytesToString(aBytes, 0, aBytes.Length)));
|
|
mStream.Write(aBytes, 0, aBytes.Length);
|
|
}
|
|
|
|
public override bool IsConnected {
|
|
get { return mStream != null; }
|
|
}
|
|
|
|
// Start is not in ctor, because for servers we have to wait for the callback. This
|
|
// however does not prevent other kind of DebugConnectorStream descendants from
|
|
// invoking this method from their constructor.
|
|
protected void Start(Stream aStream) {
|
|
DoConnected();
|
|
mStream = aStream;
|
|
Next(1, WaitForSignature);
|
|
}
|
|
|
|
public override void Dispose() {
|
|
if (mStream != null) {
|
|
mStream.Close();
|
|
mStream = null;
|
|
}
|
|
base.Dispose();
|
|
}
|
|
|
|
protected Action<byte[]> mCompletedAfterSize; // Action to call after size received
|
|
protected void SizePacket(byte[] aPacket) {
|
|
int xSize = aPacket[0] + (aPacket[1] << 8);
|
|
Next(xSize, mCompletedAfterSize);
|
|
}
|
|
|
|
protected override void Next(int aPacketSize, Action<byte[]> aCompleted) {
|
|
var xIncoming = new Incoming();
|
|
if (aPacketSize == 0) {
|
|
// Can occur with variable size packets for exampmle.
|
|
// Dont call read, becuase that will close the stream.
|
|
// So we just call the Completed directly
|
|
aCompleted(new byte[0]);
|
|
} else if (aPacketSize == -1) {
|
|
// Variable size packet, split into two reads
|
|
mCompletedAfterSize = aCompleted;
|
|
aPacketSize = 2;
|
|
xIncoming.Completed = SizePacket;
|
|
} else {
|
|
xIncoming.Completed = aCompleted;
|
|
}
|
|
xIncoming.Packet = new byte[aPacketSize];
|
|
xIncoming.Stream = mStream;
|
|
#if TRACK_PENDING
|
|
try {
|
|
Interlocked.Increment(ref _pendingReadsCount);
|
|
#endif
|
|
mStream.BeginRead(xIncoming.Packet, 0, aPacketSize, new AsyncCallback(DoRead), xIncoming);
|
|
#if TRACK_PENDING
|
|
}
|
|
catch (Exception e) {
|
|
Interlocked.Decrement(ref _pendingReadsCount);
|
|
throw;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
protected void DoRead(IAsyncResult aResult) {
|
|
try {
|
|
var xIncoming = (Incoming)aResult.AsyncState;
|
|
int xCount = xIncoming.Stream.EndRead(aResult);
|
|
|
|
System.Diagnostics.Debug.WriteLine(String.Format("DC - Received: {0}", BytesToString(xIncoming.Packet, xIncoming.CurrentPos, xCount)));
|
|
xIncoming.CurrentPos += xCount;
|
|
if (xCount == 0) {
|
|
// If 0, end of stream then just exit without calling BeginRead again
|
|
return;
|
|
}
|
|
else if (xIncoming.CurrentPos < xIncoming.Packet.Length) {
|
|
// Packet is not full yet, read more data
|
|
#if TRACK_PENDING
|
|
try {
|
|
Interlocked.Increment(ref _pendingReadsCount);
|
|
#endif
|
|
xIncoming.Stream.BeginRead(xIncoming.Packet, xIncoming.CurrentPos
|
|
, xIncoming.Packet.Length - xIncoming.CurrentPos
|
|
, new AsyncCallback(DoRead), xIncoming);
|
|
#if TRACK_PENDING
|
|
}
|
|
catch (Exception e) {
|
|
Interlocked.Decrement(ref _pendingReadsCount);
|
|
throw;
|
|
}
|
|
#endif
|
|
}
|
|
else {
|
|
// Full packet received, process it
|
|
xIncoming.Completed(xIncoming.Packet);
|
|
}
|
|
}
|
|
catch (System.IO.IOException ex) {
|
|
ConnectionLost(ex);
|
|
}
|
|
#if TRACK_PENDING
|
|
finally {
|
|
Interlocked.Decrement(ref _pendingReadsCount);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|