[SerialICE] Patch set updated for serialice: qemu-0.15.x/serialice-com: Implement TCP serialice connection
Patrick Rudolph (siro@das-labor.org)
gerrit at coreboot.org
Thu Apr 28 14:20:02 CEST 2016
Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14512
-gerrit
commit 37bf6de3a26fa15303152d0e744847bc59fc1462
Author: Patrick Rudolph <siro at das-labor.org>
Date: Mon Apr 25 12:26:12 2016 +0200
qemu-0.15.x/serialice-com: Implement TCP serialice connection
Add support for TCP connections.
Useful to connect to BeagleBone Black in EHCI Debug mode using
ser2net daemon.
Pass tcp:hostname:port instead of tty device path.
Example:
./qemu -M serialice -serialice tcp:10.0.0.1:8888
The windows version hasn't been tested yet.
Change-Id: Iee264dfd11375e11c02ea25b6887d32f3db887c5
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
SerialICE/README.QEMU | 7 ++
qemu-0.15.x/serialice-com.c | 177 ++++++++++++++++++++++++++++++++------------
2 files changed, 138 insertions(+), 46 deletions(-)
diff --git a/SerialICE/README.QEMU b/SerialICE/README.QEMU
index 3af8c36..b9d2a96 100644
--- a/SerialICE/README.QEMU
+++ b/SerialICE/README.QEMU
@@ -47,6 +47,13 @@ $ i386-softmmu/qemu -M serialice -serialice \
The device /dev/ttyS0 is the name of the serial device connected to your target
machine running the SerialICE shell.
+Instead of a local serial device you can connect over TCP to a BeagleBone Black
+running a ser2tcp server.
+The command to connect to a remote host at 10.0.0.1 port 8080 is:
+
+$ i386-softmmu/qemu -M serialice -serialice \
+ tcp:10.0.0.1:8080 -hda /dev/zero -L ./bios
+
For debugging hints see the file README.GDB
ADAPTING THE CODE
diff --git a/qemu-0.15.x/serialice-com.c b/qemu-0.15.x/serialice-com.c
index 9211b6f..85172d0 100644
--- a/qemu-0.15.x/serialice-com.c
+++ b/qemu-0.15.x/serialice-com.c
@@ -34,6 +34,9 @@
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
#endif
#include <serialice.h>
@@ -47,6 +50,7 @@ typedef struct {
#else
int fd;
#endif
+ int tcp;
char *buffer;
char *command;
} SerialICEState;
@@ -114,6 +118,7 @@ static int serialice_write(SerialICEState * state, const void *buf,
char *buffer = (char *)buf;
char c;
int i;
+ int err;
for (i = 0; i < (int)nbyte; i++) {
c = 0;
@@ -207,6 +212,10 @@ static int serialice_wait_prompt(void)
const SerialICE_target *serialice_serial_init(void)
{
+ int len = 0;
+ int port = 0;
+ char *hostname = NULL;
+
s = mallocz(sizeof(SerialICEState));
if (!s) {
@@ -217,69 +226,145 @@ const SerialICE_target *serialice_serial_init(void)
printf("You need to specify a serial device to use SerialICE.\n");
exit(1);
}
+ len = strlen(serialice_device);
+ if (len > 5) {
+ char *tmp = strstr(serialice_device, "tcp:");
+ if (tmp && tmp == serialice_device) {
+ hostname = mallocz(len - 4 + 1);
+ /* copy hostname and port */
+ memcpy(hostname, tmp + 4, len - 4);
+ /* search for port */
+ tmp = strstr(hostname, ":");
+ if (tmp) {
+ /* cut of port from hostname string */
+ *tmp = 0;
+ /* read port */
+ port = atoi(tmp + 1);
+ s->tcp = !!port;
+ }
+ }
+ }
#ifdef WIN32
- s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (s->tcp) {
+ int ret;
+ WSADATA wsaData = {0};
+ ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (ret) {
+ perror("WSAStartup failed: %d\n", ret);
+ exit(1);
+ }
- if (s->fd == INVALID_HANDLE_VALUE) {
- perror("SerialICE: Could not connect to target TTY");
- exit(1);
- }
+ s->fd = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
+ if (s->fd == INVALID_SOCKET) {
+ perror("SerialICE: Could not create a TCP socket");
+ exit(1);
+ }
+ } else {
+ s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (s->fd == INVALID_HANDLE_VALUE) {
+ perror("SerialICE: Could not connect to target TTY");
+ exit(1);
+ }
- DCB dcb;
- if (!GetCommState(s->fd, &dcb)) {
- perror("SerialICE: Could not load config for target TTY");
- exit(1);
- }
+ DCB dcb;
+ if (!GetCommState(s->fd, &dcb)) {
+ perror("SerialICE: Could not load config for target TTY");
+ exit(1);
+ }
- dcb.BaudRate = CBR_115200;
- dcb.ByteSize = 8;
- dcb.Parity = NOPARITY;
- dcb.StopBits = ONESTOPBIT;
+ dcb.BaudRate = CBR_115200;
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
- if (!SetCommState(s->fd, &dcb)) {
- perror("SerialICE: Could not store config for target TTY");
- exit(1);
+ if (!SetCommState(s->fd, &dcb)) {
+ perror("SerialICE: Could not store config for target TTY");
+ exit(1);
+ }
}
#else
- s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (s->tcp) {
+ struct timeval tv;
+ s->fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (s->fd == -1) {
+ perror("SerialICE: Could not create a TCP socket");
+ exit(1);
+ }
- if (s->fd == -1) {
- perror("SerialICE: Could not connect to target TTY");
- exit(1);
- }
+ if (fcntl(s->fd, F_SETFL, 0) == -1) {
+ perror("SerialICE: Could not switch to blocking I/O");
+ exit(1);
+ }
- if (ioctl(s->fd, TIOCEXCL) == -1) {
- perror("SerialICE: TTY not exclusively available");
- exit(1);
- }
+ tv.tv_sec = 1; /* 1 second timeout */
+ tv.tv_usec = 0;
+ setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
+ } else {
+ s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (s->fd == -1) {
+ perror("SerialICE: Could not connect to target TTY");
+ exit(1);
+ }
- if (fcntl(s->fd, F_SETFL, 0) == -1) {
- perror("SerialICE: Could not switch to blocking I/O");
- exit(1);
- }
+ if (ioctl(s->fd, TIOCEXCL) == -1) {
+ perror("SerialICE: TTY not exclusively available");
+ exit(1);
+ }
- if (tcgetattr(s->fd, &options) == -1) {
- perror("SerialICE: Could not get TTY attributes");
- exit(1);
- }
+ if (fcntl(s->fd, F_SETFL, 0) == -1) {
+ perror("SerialICE: Could not switch to blocking I/O");
+ exit(1);
+ }
- cfsetispeed(&options, B115200);
- cfsetospeed(&options, B115200);
+ if (tcgetattr(s->fd, &options) == -1) {
+ perror("SerialICE: Could not get TTY attributes");
+ exit(1);
+ }
+
+ cfsetispeed(&options, B115200);
+ cfsetospeed(&options, B115200);
- /* set raw input, 1 second timeout */
- options.c_cflag |= (CLOCAL | CREAD);
- options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
- options.c_oflag &= ~OPOST;
- options.c_iflag |= IGNCR;
- options.c_cc[VMIN] = 0;
- options.c_cc[VTIME] = 100;
+ /* set raw input, 1 second timeout */
+ options.c_cflag |= (CLOCAL | CREAD);
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ options.c_oflag &= ~OPOST;
+ options.c_iflag |= IGNCR;
+ options.c_cc[VMIN] = 0;
+ options.c_cc[VTIME] = 100;
- tcsetattr(s->fd, TCSANOW, &options);
+ tcsetattr(s->fd, TCSANOW, &options);
- tcflush(s->fd, TCIOFLUSH);
+ tcflush(s->fd, TCIOFLUSH);
+ }
#endif
+ if (s->tcp) {
+ struct hostent *server;
+ struct sockaddr_in serv_addr;
+
+ server = gethostbyname(hostname);
+ if (server == NULL) {
+ perror("No such host.\n");
+ exit(1);
+ }
+
+ bzero((char *) &serv_addr, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ bcopy((char *)server->h_addr,
+ (char *)&serv_addr.sin_addr.s_addr,
+ server->h_length);
+ serv_addr.sin_port = htons(port);
+
+ printf("Connecting to tcp://%s:%d ...\n", hostname, port);
+
+ if (connect(s->fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+ perror("ERROR connecting");
+ exit(1);
+ }
+ printf("Connected to tcp://%s:%d .\n", hostname, port);
+ }
+
s->buffer = mallocz(BUFFER_SIZE);
s->command = mallocz(BUFFER_SIZE);
if (!s->buffer || !s->command) {
More information about the SerialICE
mailing list