- added new serial modes based on SF patch #1928848 by Eugene Toder
* "pipe-server" (win32 only): It makes bochs a named pipe server so other application can communicate with it using pipes API. Useful e.g. for remote kernel debugging. * "pipe-client" (win32 only) * "socket-server": for the use with gdb
This commit is contained in:
parent
4e091f2a3a
commit
966f2c8133
@ -426,18 +426,29 @@ debugger_log: -
|
||||
# Then do `sleep 1000000' in the com1 window to keep the shell from
|
||||
# messing with things, and run bochs in the other window. Serial I/O to
|
||||
# com1 (port 0x3f8) will all go to the other window.
|
||||
# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe
|
||||
# client or server. In client mode it connects to an already running server (if
|
||||
# connection fails Bochs treats com port as not connected). In server mode it
|
||||
# opens socket/named pipe and waits until a client application connects to it
|
||||
# before starting simulation. This mode is useful for remote debugging (e.g.
|
||||
# with gdb's "target remote host:port" command or windbg's command line option
|
||||
# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for
|
||||
# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP
|
||||
# communication, pipe modes use duplex byte mode pipes.
|
||||
# Other serial modes are 'null' (no input/output), 'file' (output to a file
|
||||
# specified as the 'dev' parameter), 'raw' (use the real serial port - under
|
||||
# construction for win32), 'mouse' (standard serial mouse - requires
|
||||
# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys')
|
||||
# and 'socket' (connect a networking socket).
|
||||
# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys').
|
||||
#
|
||||
# Examples:
|
||||
# com1: enabled=1, mode=null
|
||||
# com1: enabled=1, mode=mouse
|
||||
# com2: enabled=1, mode=file, dev=serial.out
|
||||
# com3: enabled=1, mode=raw, dev=com1
|
||||
# com3: enabled=1, mode=socket, dev=localhost:8888
|
||||
# com3: enabled=1, mode=socket-client, dev=localhost:8888
|
||||
# com3: enabled=1, mode=socket-server, dev=localhost:8888
|
||||
# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe
|
||||
# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe
|
||||
#=======================================================================
|
||||
#com1: enabled=1, mode=term, dev=/dev/ttyp9
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: config.cc,v 1.133 2008-03-30 14:32:13 sshwarts Exp $
|
||||
// $Id: config.cc,v 1.134 2008-05-22 08:13:21 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -1253,10 +1253,15 @@ void bx_init_options()
|
||||
static const char *serial_mode_list[] = {
|
||||
"null",
|
||||
"file",
|
||||
"pipe",
|
||||
"pipe-client",
|
||||
"pipe-server",
|
||||
"term",
|
||||
"raw",
|
||||
"mouse",
|
||||
"socket",
|
||||
"socket-client",
|
||||
"socket-server",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -1273,7 +1278,7 @@ void bx_init_options()
|
||||
enabled = new bx_param_bool_c(menu, "enabled", label, descr,
|
||||
(i==0)?1 : 0); // only enable the first by default
|
||||
sprintf(label, "I/O mode of the serial device for COM%d", i+1);
|
||||
sprintf(descr, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket'");
|
||||
sprintf(descr, "The mode can be one these: 'null', 'file', 'pipe', 'term', 'raw', 'mouse', 'socket'");
|
||||
mode = new bx_param_enum_c(menu, "mode", label, descr,
|
||||
serial_mode_list, 0, 0);
|
||||
mode->set_ask_format("Choose I/O mode of the serial device [%s] ");
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
================================================================
|
||||
doc/docbook/user/user.dbk
|
||||
$Id: user.dbk,v 1.238 2008-05-12 18:46:46 vruppert Exp $
|
||||
$Id: user.dbk,v 1.239 2008-05-22 08:13:21 vruppert Exp $
|
||||
|
||||
This is the top level file for the Bochs Users Manual.
|
||||
================================================================
|
||||
@ -3646,7 +3646,10 @@ Examples:
|
||||
com1: enabled=1, mode=term, dev=/dev/ttyp9
|
||||
com2: enabled=1, mode=file, dev=serial.out
|
||||
com3: enabled=1, mode=raw, dev=com1
|
||||
com3: enabled=1, mode=socket, dev=localhost:8888
|
||||
com3: enabled=1, mode=socket-client, dev=localhost:8888
|
||||
com3: enabled=1, mode=socket-server, dev=localhost:8888
|
||||
com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe
|
||||
com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe
|
||||
</screen>
|
||||
This defines a serial port (UART type 16550A).
|
||||
</para>
|
||||
@ -3660,12 +3663,24 @@ Examples:
|
||||
things, and run Bochs in the other window. Serial I/O to com1 (port 0x3f8)
|
||||
will all go to the other window.
|
||||
</para>
|
||||
<para>
|
||||
When using socket* and pipe* (win32 only) modes Bochs becomes either
|
||||
socket/named pipe client or server. In client mode it connects to an already
|
||||
running server (if connection fails Bochs treats com port as not connected).
|
||||
In server mode it opens socket/named pipe and waits until a client application
|
||||
connects to it before starting simulation. This mode is useful for remote
|
||||
debugging (e.g. with gdb's "target remote host:port" command or windbg's command
|
||||
line option -k com:pipe,port=\\.\pipe\pipename).
|
||||
|
||||
Note: 'socket' is a shorthand for 'socket-client', 'pipe' for 'pipe-client'.
|
||||
Socket modes use simple TCP communication, pipe modes use duplex byte mode pipes.
|
||||
</para>
|
||||
<para>
|
||||
Other serial modes are 'null' (no input/output), 'file' (output to a file
|
||||
specified as the 'dev' parameter), 'raw' (use the real serial port - under
|
||||
construction for win32), 'mouse' (standard serial mouse - requires
|
||||
<link linkend="bochsopt-mouse">mouse option</link> setting 'type=serial'
|
||||
or 'type=serial_wheel') and 'socket' (connect a networking socket).
|
||||
or 'type=serial_wheel').
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial.cc,v 1.81 2008-02-15 22:05:43 sshwarts Exp $
|
||||
// $Id: serial.cc,v 1.82 2008-05-22 08:13:22 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2004 MandrakeSoft S.A.
|
||||
@ -41,6 +41,11 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define closesocket(s) close(s)
|
||||
#else
|
||||
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_RAW_SERIAL
|
||||
@ -104,7 +109,13 @@ bx_serial_c::~bx_serial_c(void)
|
||||
#endif
|
||||
break;
|
||||
case BX_SER_MODE_SOCKET:
|
||||
if (BX_SER_THIS s[i].socket_id >= 0) ::close(BX_SER_THIS s[i].socket_id);
|
||||
if (BX_SER_THIS s[i].socket_id >= 0) closesocket(BX_SER_THIS s[i].socket_id);
|
||||
break;
|
||||
case BX_SER_MODE_PIPE:
|
||||
#ifdef WIN32
|
||||
if (BX_SER_THIS s[i].pipe)
|
||||
CloseHandle(BX_SER_THIS s[i].pipe);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -295,16 +306,17 @@ bx_serial_c::init(void)
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_MOUSE;
|
||||
BX_SER_THIS mouse_port = i;
|
||||
BX_SER_THIS mouse_type = SIM->get_param_enum(BXPN_MOUSE_TYPE)->get();
|
||||
} else if (!strcmp(mode, "socket")) {
|
||||
} else if (!strncmp(mode, "socket", 6)) {
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_SOCKET;
|
||||
struct sockaddr_in sin;
|
||||
struct hostent *hp;
|
||||
char host[BX_PATHNAME_LEN];
|
||||
int port;
|
||||
int socket;
|
||||
bx_bool server = !strcmp(mode, "socket-server");
|
||||
|
||||
#if defined(WIN32)
|
||||
static bool winsock_init = false;
|
||||
static bx_bool winsock_init = false;
|
||||
if (!winsock_init) {
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
@ -339,19 +351,81 @@ bx_serial_c::init(void)
|
||||
sin.sin_port = htons (port);
|
||||
|
||||
socket = ::socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (socket < 0) {
|
||||
if (socket < 0)
|
||||
BX_PANIC(("com%d: socket() failed",i+1));
|
||||
}
|
||||
|
||||
if (::connect (socket, (sockaddr *) &sin, sizeof (sin)) < 0) {
|
||||
// server mode
|
||||
if (server) {
|
||||
if (::bind (socket, (sockaddr *) &sin, sizeof (sin)) < 0 ||
|
||||
::listen (socket, SOMAXCONN) < 0) {
|
||||
closesocket(socket);
|
||||
socket = -1;
|
||||
BX_PANIC(("com%d: bind() or listen() failed (host:%s, port:%d)",i+1, host, port));
|
||||
}
|
||||
else {
|
||||
BX_INFO(("com%d: waiting for client to connect (host:%s, port:%d)",i+1, host, port));
|
||||
int client;
|
||||
if ((client = ::accept (socket, NULL, 0)) < 0)
|
||||
BX_PANIC(("com%d: accept() failed (host:%s, port:%d)",i+1, host, port));
|
||||
closesocket(socket);
|
||||
socket = client;
|
||||
}
|
||||
}
|
||||
// client mode
|
||||
else if (::connect (socket, (sockaddr *) &sin, sizeof (sin)) < 0) {
|
||||
closesocket(socket);
|
||||
socket = -1;
|
||||
BX_INFO(("com%d: connect() failed (host:%s, port:%d)",i+1, host, port));
|
||||
} else {
|
||||
BX_INFO(("com%d - inet - socket_id: %d, ip:%s, port:%d", i+1, socket, host, port));
|
||||
}
|
||||
|
||||
BX_SER_THIS s[i].socket_id = socket;
|
||||
if (socket > 0)
|
||||
BX_INFO(("com%d - inet %s - socket_id: %d, ip:%s, port:%d",
|
||||
i+1, server ? "server" : "client", socket, host, port));
|
||||
} else if (!strncmp(mode, "pipe", 4)) {
|
||||
if (strlen(dev) > 0) {
|
||||
bx_bool server = !strcmp(mode, "pipe-server");
|
||||
#ifdef WIN32
|
||||
HANDLE pipe;
|
||||
|
||||
BX_SER_THIS s[i].io_mode = BX_SER_MODE_PIPE;
|
||||
|
||||
// server mode
|
||||
if (server) {
|
||||
pipe = CreateNamedPipe( dev,
|
||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1, 4096, 4096, 0, NULL);
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
BX_PANIC(("com%d: CreateNamedPipe(%s) failed", i+1, dev));
|
||||
|
||||
BX_INFO(("com%d: waiting for client to connect to %s", i+1, dev));
|
||||
if (!ConnectNamedPipe(pipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
CloseHandle(pipe);
|
||||
pipe = INVALID_HANDLE_VALUE;
|
||||
BX_PANIC(("com%d: ConnectNamedPipe(%s) failed", i+1, dev));
|
||||
}
|
||||
}
|
||||
// client mode
|
||||
else {
|
||||
pipe = CreateFile( dev,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
BX_INFO(("com%d: failed to open pipe %s", i+1, dev));
|
||||
}
|
||||
|
||||
if (pipe != INVALID_HANDLE_VALUE)
|
||||
BX_SER_THIS s[i].pipe = pipe;
|
||||
#else
|
||||
BX_PANIC(("support for serial mode '%s' not available", mode));
|
||||
#endif
|
||||
}
|
||||
} else if (strcmp(mode, "null")) {
|
||||
BX_PANIC(("unknown serial i/o mode"));
|
||||
BX_PANIC(("unknown serial i/o mode '%s'", mode));
|
||||
}
|
||||
// simulate device connected
|
||||
if (BX_SER_THIS s[i].io_mode != BX_SER_MODE_RAW) {
|
||||
@ -1230,6 +1304,14 @@ bx_serial_c::tx_timer(void)
|
||||
(bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1);
|
||||
#endif
|
||||
}
|
||||
case BX_SER_MODE_PIPE:
|
||||
#ifdef WIN32
|
||||
if (BX_SER_THIS s[port].pipe) {
|
||||
DWORD written;
|
||||
WriteFile(BX_SER_THIS s[port].pipe, (bx_ptr_t)& BX_SER_THIS s[port].tsrbuffer, 1, &written, NULL);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1388,6 +1470,17 @@ bx_serial_c::rx_timer(void)
|
||||
data_ready = 1;
|
||||
}
|
||||
break;
|
||||
case BX_SER_MODE_PIPE:
|
||||
#ifdef WIN32
|
||||
DWORD avail = 0;
|
||||
if (BX_SER_THIS s[port].pipe &&
|
||||
PeekNamedPipe(BX_SER_THIS s[port].pipe, NULL, 0, NULL, &avail, NULL) &&
|
||||
avail > 0) {
|
||||
ReadFile(BX_SER_THIS s[port].pipe, &chbuf, 1, &avail, NULL);
|
||||
data_ready = 1;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (data_ready) {
|
||||
if (!BX_SER_THIS s[port].modem_cntl.local_loopback) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial.h,v 1.33 2008-01-26 22:24:02 sshwarts Exp $
|
||||
// $Id: serial.h,v 1.34 2008-05-22 08:13:22 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2004 MandrakeSoft S.A.
|
||||
@ -75,6 +75,7 @@ extern "C" {
|
||||
#define BX_SER_MODE_RAW 3
|
||||
#define BX_SER_MODE_MOUSE 4
|
||||
#define BX_SER_MODE_SOCKET 5
|
||||
#define BX_SER_MODE_PIPE 6
|
||||
|
||||
enum {
|
||||
BX_SER_INT_IER,
|
||||
@ -119,6 +120,9 @@ typedef struct {
|
||||
int tty_id;
|
||||
int socket_id;
|
||||
FILE *output;
|
||||
#ifdef WIN32
|
||||
HANDLE pipe;
|
||||
#endif
|
||||
|
||||
#if USE_RAW_SERIAL
|
||||
serial_raw* raw;
|
||||
|
Loading…
x
Reference in New Issue
Block a user