Vmware Esx Server - how to connect a serial port to a virtual machine

 

Some softwares running on virtual machines need to connect to the serial port (COM) to communicate with a serial device, but Esx server doesn't share the physical serial port to the virtual machines. How to do?

In my case I had the need to connect a proprietary software running on a windows virtual machine (living into an Esx server) to a led display managed through the serial port.

This is what I did:

I physically connected the led display to a the serial port of a unix server (/dev/ttyS0). I used ser2net to bridge the serial port over a network port (tcp/1001) and I connected the display management tool to the ethernet port.

 

Serial over ethernet configuration

On the linux host:

First some checks: are serial ports connected to the system and well configured?

dmesg | grep tty
ttyS0 at 0x03f8 (irq = 4) is a 16550A
ttyS1 at 0x02f8 (irq = 3) is a 16550A

setserial -g /dev/ttyS[01]
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3

To test if the serial port was working as expected I connected it to the serial management port of a Cisco device and I connected to the terminal through minicom

apt-get install minicom

then I did

1) minicom -s, to enter configuration mode: it opens a text-based menu. Note: Use "ENTER" to exit any menus except the main menu.
2) under "Serial Port Setup" mine was set to default /dev/ttyS0 and 38400. I had to manually change it to 9600. Remember to hit ENTER to exit, do NOT try to use "Q" to "Quit"
3) under "Modem and Dialing" remove the "Init String". Anything in this field will be sent to the device when you connect.
4) from the main menu use "Save setup to DFL" to create a new default config file for minicom.

(thanks anonymous)

running

minicom

I could see the Cisco command prompt, so the port was working as expected and I went forward to the serial bridging over the ethernet.

 

I tried several software but ser2net is absolutely the best because it allows a fine tuning of the com port parameters.

Ser2net is available on the debian repository but I preferred to compile it from its latest release (at the time of writing is 2.7) and it can be installed as common with configure make and make install.

x3400:~# which ser2net
/usr/local/sbin/ser2net

Unfortunately the documentation isn't so easy and ready to go: it lacks examples.

This is its configuration file:

x3400:~# cat /etc/ser2net.conf
#
# This is an example configuration file for ser2net.  It has the following
# format:
#  <TCP port>:<state>:<timeout>:<device>:<options>
#     TCP port
#            Name   or  number of the TCP/IP port to accept con-
#            nections from for this device.  A port number may
#            be of the form [host,]port, such as 127.0.0.1,2000
#            or localhost,2000.  If this is specified, it will
#            only bind to the IP address specified. Otherwise
#            it will bind to all the ports on the machine.
#
#     state  Either raw or rawlp or telnet or off.  off disables
#            the  port  from  accepting  connections.  It can be
#            turned on later from the control port.  raw enables
#            the port and  transfers  all data as-is between the
#            port  and  the long.  rawlp  enables  the port  and
#            transfers  all input data to device, device is open
#            without  any  termios  setting.  It  allow  to  use
#            /dev/lpX  devices  and  printers connected to them.
#            telnet enables the port and runs the telnet  proto-
#            col  on the port to set up telnet parameters.  This
#            is most useful for using telnet.
#
#     timeout
#            The time (in seconds) before the port will be  dis-
#            connected  if  there  is no activity on it.  A zero
#            value disables this function.
#
#     device The  name  of  the  device   to  connect  to.  This
#            must be in the form of /dev/<device>.
#
#     options
#            Sets  operational  parameters  for the serial port.
#            Options 300, 1200, 2400, 4800, 9600, 19200, 38400,
#            57600, 115200 set the various baud rates.  EVEN,
#            ODD, NONE set the parity.  1STOPBIT, 2STOPBITS set
#            the number of stop bits.  7DATABITS, 8DATABITS set
#            the number of data bits.  [-]XONXOFF turns on (-
#            off) XON/XOFF support.  [-]RTSCTS turns on (- off)
#            hardware flow control, [-]LOCAL turns off (- on)
#            monitoring of the modem lines, and
#            [-]HANGUP_WHEN_DONE turns on (- off) lowering the
#            modem control lines when the connection is done.
#            NOBREAK disables automatic setting of the break
#            setting of the serial port.
#            The "remctl" option allow remote control (ala RFC
#            2217) of serial-port configuration.  A banner name
#            may also be specified, that banner will be printed
#            for the line.  If no banner is given, then no
#            banner is printed.
#            The tw, tr, and tb options take a tracefile name (
#            specified in TRACEFILE that will take all traced data.
#            tw is data written to the device, tr is data read from
#            the device, and tb is both.
#
# or...

#  BANNER:<banner name>:banner
#    This will create a banner, if the banner name is given in the
#    options of a line, that banner will be printed.  This takes the
#    standard "C" \x characters (\r is carraige return, \n is newline,
#    etc.).  It also accepts \d, which prints the device name, \p,
#    which prints the TCP port number, and \s which prints the serial
#    parameters (eg 9600N81).  Banners can span lines if the last
#    character on a line is '\'.  Note that you *must* use \r\n to
#    start a new line.
#
#  TRACEFILE:<name>:filename
#    This specifies a filename to trace output into, as tw:/tmp/trace1.
#    This takes a large number of escape sequences, see the man page
#    for details on these options.
#
# Note that the same device can be listed multiple times under different
# ports, this allows the same serial port to have both telnet and raw
# protocols.

BANNER:banner1:Welcome to ser2net TCP port \p device \d\r\n\
second line \
third line\r\n

BANNER:banner2:this is ser2net TCP port \p device \d\r\n\
second line \
third line\r\n

BANNER:banner3:this is ser2net TCP port \p device \d  serial parms \s\r\n

TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U
TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U

1001:raw:600:/dev/ttyS0:9600 EVEN
#2001:raw:600:/dev/ttyS0:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2002:raw:600:/dev/ttyS1:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2003:raw:5:/dev/ttyS2:9600 #2004:raw:5:/dev/ttyS3:115200 #2005:raw:5:/dev/ttyS4:9600 #2006:raw:5:/dev/ttyS5:9600 #2007:raw:5:/dev/ttyS6:9600 tw=tw1 tr=tr1 #3001:telnet:0:/dev/ttyS0:19200 remctl banner1 #3011:telnet:3:/dev/ttyS0:19200 banner2 #3002:telnet:0:/dev/ttyS1:9600 #3003:telnet:0:/dev/ttyS2:9600 banner3 #3004:telnet:0:/dev/ttyS3:115200 #3005:telnet:0:/dev/ttyS4:9600 #3006:telnet:0:/dev/ttyS5:9600 #3007:telnet:0:/dev/ttyS6:9600 #5001:rawlp:10:/dev/lp0
x3400:~# cat /etc/ser2net.conf
#
# This is an example configuration file for ser2net.  It has the following
# format:
#  <TCP port>:<state>:<timeout>:<device>:<options>
#     TCP port
#            Name   or  number of the TCP/IP port to accept con-
#            nections from for this device.  A port number may
#            be of the form [host,]port, such as 127.0.0.1,2000
#            or localhost,2000.  If this is specified, it will
#            only bind to the IP address specified. Otherwise
#            it will bind to all the ports on the machine.
#
#     state  Either raw or rawlp or telnet or off.  off disables
#            the  port  from  accepting  connections.  It can be
#            turned on later from the control port.  raw enables
#            the port and  transfers  all data as-is between the
#            port  and  the long.  rawlp  enables  the port  and
#            transfers  all input data to device, device is open
#            without  any  termios  setting.  It  allow  to  use
#            /dev/lpX  devices  and  printers connected to them.
#            telnet enables the port and runs the telnet  proto-
#            col  on the port to set up telnet parameters.  This
#            is most useful for using telnet.
#
#     timeout
#            The time (in seconds) before the port will be  dis-
#            connected  if  there  is no activity on it.  A zero
#            value disables this function.
#
#     device The  name  of  the  device   to  connect  to.  This
#            must be in the form of /dev/<device>.
#
#     options
#            Sets  operational  parameters  for the serial port.
#            Options 300, 1200, 2400, 4800, 9600, 19200, 38400,
#            57600, 115200 set the various baud rates.  EVEN,
#            ODD, NONE set the parity.  1STOPBIT, 2STOPBITS set
#            the number of stop bits.  7DATABITS, 8DATABITS set
#            the number of data bits.  [-]XONXOFF turns on (-
#            off) XON/XOFF support.  [-]RTSCTS turns on (- off)
#            hardware flow control, [-]LOCAL turns off (- on)
#            monitoring of the modem lines, and
#            [-]HANGUP_WHEN_DONE turns on (- off) lowering the
#            modem control lines when the connection is done. 
#            NOBREAK disables automatic setting of the break
#            setting of the serial port.
#            The "remctl" option allow remote control (ala RFC
#            2217) of serial-port configuration.  A banner name
#            may also be specified, that banner will be printed
#            for the line.  If no banner is given, then no
#            banner is printed.
#            The tw, tr, and tb options take a tracefile name (
#            specified in TRACEFILE that will take all traced data.
#            tw is data written to the device, tr is data read from
#            the device, and tb is both.
#
# or...

#  BANNER:<banner name>:banner
#    This will create a banner, if the banner name is given in the
#    options of a line, that banner will be printed.  This takes the
#    standard "C" \x characters (\r is carraige return, \n is newline,
#    etc.).  It also accepts \d, which prints the device name, \p,
#    which prints the TCP port number, and \s which prints the serial
#    parameters (eg 9600N81).  Banners can span lines if the last
#    character on a line is '\'.  Note that you *must* use \r\n to
#    start a new line.
#
#  TRACEFILE:<name>:filename
#    This specifies a filename to trace output into, as tw:/tmp/trace1.
#    This takes a large number of escape sequences, see the man page
#    for details on these options.
#
# Note that the same device can be listed multiple times under different
# ports, this allows the same serial port to have both telnet and raw
# protocols.

BANNER:banner1:Welcome to ser2net TCP port \p device \d\r\n\
second line \
third line\r\n

BANNER:banner2:this is ser2net TCP port \p device \d\r\n\
second line \
third line\r\n

BANNER:banner3:this is ser2net TCP port \p device \d  serial parms \s\r\n

TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U
TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U

1001:raw:600:/dev/ttyS0:9600 EVEN
#2001:raw:600:/dev/ttyS0:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS
#2002:raw:600:/dev/ttyS1:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS
#2003:raw:5:/dev/ttyS2:9600
#2004:raw:5:/dev/ttyS3:115200
#2005:raw:5:/dev/ttyS4:9600
#2006:raw:5:/dev/ttyS5:9600
#2007:raw:5:/dev/ttyS6:9600 tw=tw1 tr=tr1
#3001:telnet:0:/dev/ttyS0:19200 remctl banner1
#3011:telnet:3:/dev/ttyS0:19200 banner2
#3002:telnet:0:/dev/ttyS1:9600
#3003:telnet:0:/dev/ttyS2:9600 banner3
#3004:telnet:0:/dev/ttyS3:115200
#3005:telnet:0:/dev/ttyS4:9600
#3006:telnet:0:/dev/ttyS5:9600
#3007:telnet:0:/dev/ttyS6:9600
#5001:rawlp:10:/dev/lp0

This row

1001:raw:600:/dev/ttyS0:9600 EVEN

means that the serial port /dev/ttyS0 (COM1 in windows) will be connected raw to the tcp/1001 port. 600 in the timeout, 9600 is the baud rate. EVEN sets the parity: generally is set to NONE but in my case I spent several hours on tests before to understand that was the problem avoiding me to communicate with the proprietary software (of course there wasn't a word about that in the documentation)

Ser2net can be launched from a console:

ser2net -d

Using netstat and fuser I can double check if ser2net is listening on the given port

x3400:~# netstat -ltpn Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:2049            0.0.0.0:*               LISTEN      -              
tcp        0      0 0.0.0.0:47556           0.0.0.0:*               LISTEN      3381/rpc.mountd
tcp        0      0 127.0.0.1:709           0.0.0.0:*               LISTEN      3501/famd      
tcp        0      0 0.0.0.0:1001            0.0.0.0:*               LISTEN      8704/ser2net    tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      2804/portmap   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      8313/vmware-convert
tcp        0      0 0.0.0.0:113             0.0.0.0:*               LISTEN      3392/inetd     
tcp        0      0 0.0.0.0:49138           0.0.0.0:*               LISTEN      -              
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3186/sshd      
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      3314/cupsd     
tcp        0      0 0.0.0.0:43895           0.0.0.0:*               LISTEN      2816/rpc.statd 
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      3462/master    
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      8687/4         
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      8313/vmware-convert
tcp        0      0 0.0.0.0:3551            0.0.0.0:*               LISTEN      3594/apcupsd   
tcp6       0      0 :::139                  :::*                    LISTEN      3478/smbd      
tcp6       0      0 :::5900                 :::*                    LISTEN      6231/vino-server
tcp6       0      0 :::80                   :::*                    LISTEN      8313/vmware-convert
tcp6       0      0 :::22                   :::*                    LISTEN      3186/sshd      
tcp6       0      0 ::1:6010                :::*                    LISTEN      8687/4         
tcp6       0      0 :::443                  :::*                    LISTEN      8313/vmware-convert
tcp6       0      0 :::445                  :::*                    LISTEN      3478/smbd     

OR

x3400:~# fuser -n tcp 1001
1001/tcp:             8704

x3400:~# ps aux | grep 8704
root      8704  0.0  0.0   6008   568 pts/1    S+   10:50   0:00 ser2net -d

 

Lucky me the proprietary tool to manage the led display is capable to connect over the network so, after discovering the "even parity thing" I successfully connected to the ethernet port and then to the led display.

... but I was curious and I tried to make a real serial over ethernet bridge: physical serial (host1) -> ethernet -> virtual serial (virtual machine)

I used com0com a tool for windows (* linux version) and its related tools : I read com0com documentation and hub4com the readme.txt (com2tcp, hub4com) included and I was capable to make the bridge but my display management application didn't connect .... probably due to the parity issue.

 

Starting ser2net as a service at boot

The compiled version of ser2net obviously doesn't set itself as a daemon to be started at boot time, so I added it manually. (The debian package should already provide it)

vim /etc/init.d/serial2network
#! /bin/bash

### BEGIN INIT INFO
# Provides:        ser2net
# Required-Start:   
# Required-Stop:   
# Default-Start:    2 3 4 5
# Default-Stop:        1
# Short-Description:    serial over ethernet
### END INIT INFO

kill_pid() {
    PID=$(pidof "$1")
    if [ "$PID" != "" ]
    then
#        echo "PID "$PID
        pidof "$1" | xargs kill  
    fi
}


if [ ! -e "/usr/local/sbin/ser2net" ]
then
  echo "ser2net is not installed"
  exit 1
fi

if [ ! -e "/etc/ser2net.conf" ]
then
  echo "ser2net config file is missing"
  exit 1
fi


case "$1" in
  start)
    echo "Stopping previous ser2net..."
    echo
    kill_pid "ser2net"   
    echo "Starting ser2net"
    /usr/local/sbin/ser2net
    if [ "$?" == "0" ]
    then
        echo "done"
    else
        echo "not started"
    fi
    ;;
  stop)
    echo "Stopping ser2net"
    kill_pid ser2net
    echo "done"
    ;;

  *)
    echo "Usage: /etc/init.d/serial2network {start|stop}"
    exit 1
esac

exit 0

and finally I added it to the starting services

x3400:~# update-rc.d serial2network defaults
 Adding system startup for /etc/init.d/serial2network ...
   /etc/rc0.d/K20serial2network -> ../init.d/serial2network
   /etc/rc1.d/K20serial2network -> ../init.d/serial2network
   /etc/rc6.d/K20serial2network -> ../init.d/serial2network
   /etc/rc2.d/S20serial2network -> ../init.d/serial2network
   /etc/rc3.d/S20serial2network -> ../init.d/serial2network
   /etc/rc4.d/S20serial2network -> ../init.d/serial2network
   /etc/rc5.d/S20serial2network -> ../init.d/serial2network

 

-----------------

Just a note for windows users: during my never ending tests I found this tool Virtual Serial Port Driver. It comes as a trial version expiring after a couple of weeks. I tried it and it worked smoothly.

 

References:

linux serial console howto

serialproxy: it works and it's easy to set up but it lacks the possibility to configure the serial parameters (in my case it turned to be a must!)

* remserial: another software similiar to ser2net (not tried). It seems good to perform a serial bridge over the ethernet for 2 unix hosts. I mean: physical serial (host1) -> ethernet -> virtual serial (host2)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
4 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.