Serial communication between QEMU host and guest - serial-port

I'm trying to set up a pair of serial ports between my QEMU host (Debian Jessie x86_64) and guest (also Debian Jessie, but on ARM). Everything except the serial port part works.
I'm really new to QEMU so there might be a better way but I've tested the following flags when running QEMU:
-chardev tty,id=mytty,path=/dev/pts/2 (/dev/pts/2 & 3 are up with socat)
-chardev pty,id=mypty QEMU opens a PTY but when I try to read or write from host get permission denied.
In either case I can't find the ports in my guest. /dev/pts is empty and in /dev there are only tty and ttyAMA3. So, my problem is setting up communication in general and I'm especially curious on where the ports are on my guest.

I found a solution to my own question. First the device tree was incomplete so I needed to add 3 additional uart ports. That's the reason I could not find my ports in the guest.
Second, I needed to tell QEMU to use on of the ports as stdio: -append ... console=ttyAMA3 and -serial mon:stdio. Then I'm able to, with -serial pty, link QEMUs ttyAMA* to pts/* on the host.

Related

Qemu - Redirect host input to guest UART for bare metal kernel

I'm writing a kernel from scratch in Rust for 64-bit ARM devices. For testing purpose, I use Qemu virt machine.
Currently, I'm able to write characters from guest to host console through UART. Now I would like to do the opposite, i.e. send characters from host console to guest UART port. Is there a way to do this? Should I add some arguments to Qemu?
I run Qemu virt machine with the following arguments:
qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -serial pty -S -kernel target/aarch64-unknown-none/debug/cortex-a57
It gives me a new pty that I can attach with screen /dev/pts/mypty. Then I run the program tapping c in Qemu console.
I would like to use the same pty (or a new one?) to write data to the guest.
QEMU always redirects both input and output for a guest UART to the same place; this is true of all of '-serial stdio', '-nographic' (which does an implicit '-serial mon:stdio') and '-serial pty'. So you don't need to do anything extra. If UART input is not working then the problem seems likely to be a bug in your guest code.
Just read the same TTY as Qemu redirects all input to the same place.

Unable to remote debug gdbserver over serial port

I'm trying to remote debug using gdbserver.
I connect my target device to my PC through USB port using this command to open terminal controlling my device :
minicom -D "/dev/ttyUSB0".
Now on my target device, I need to run gdbserver with this cmd:
gdbserver /dev/my_USB_serial_port my_Program.
However, I can't find ttyUSB0, all I got ís a bunch of ttyx(with x is a number) as below:
~ # /dev/tty
tty tty14 tty20 tty27 tty33 tty4 tty46 tty52 tty59 tty8
tty0 tty15 tty21 tty28 tty34 tty40 tty47 tty53 tty6 tty9
tty1 tty16 tty22 tty29 tty35 tty41 tty48 tty54 tty60 ttyS0
tty10 tty17 tty23 tty3 tty36 tty42 tty49 tty55 tty61 ttyS1
tty11 tty18 tty24 tty30 tty37 tty43 tty5 tty56 tty62
tty12 tty19 tty25 tty31 tty38 tty44 tty50 tty57 tty63
tty13 tty2 tty26 tty32 tty39 tty45 tty51 tty58 tty7
How could I find which one is the correct serial port of my USB port ?
Update 1: As Employed Russian mentioned in the answer, I got confused about the USB port but I still couldn't connect to gdbserver using his command.
However, I can't find ttyUSB0
You are confused -- of course you will not find ttyUSB0 on the target -- the target doesn't have anything plugged into its USB port.
On the target, you want to run gdbserver - my_Program &, then disconnect minicom, and finally use gdb and target remote /dev/ttyUSB0 on the host.
Make sure getty isn't running on the same serial port as gdbserver on the target.
If you've got an interactive shell with minicom, check the serial port (usually ttyS0) on the target that's connected to it. If it's ttyS0, you start gdbserver on some other port, and connect another FTDI cable from that port to a second USB port on your host.

Unable to execute MPICH2 on multiple machines on ubuntu 12.04 (HYDU_sock_connect issue)

I am facing difficulty in executing MPI program on two machines. The OS is Ubuntu 12.04. And the MPI implementation is MPICH2
ssh is working fine:
root#ubuntu:/home# ssh 192.168.1.9
root#gpuguy's password:
Welcome to Ubuntu 12.04.3 LTS (GNU/Linux 3.8.0-29-generic i686)
* Documentation: https://help.ubuntu.com/
131 packages can be updated.
67 updates are security updates.
Last login: Thu Oct 24 17:36:25 2013 from ubuntu.local
root#gpuguy:~#
But when I run my MPI programs it fails:
root#ubuntu:/home# mpiexec -f hosts.cfg -n 4 hello
root#192.168.1.9's password:
[proxy:0:0#gpuguy] HYDU_sock_connect (./utils/sock/sock.c:171): unable to get host address for ubuntu (1)
[proxy:0:0#gpuguy] main (./pm/pmiserv/pmip.c:209): unable to connect to server ubuntu at port 42104 (check for firewalls!)
I have already disabled firewall on both machines that is the reason I can do ssh successfully. But how to solve this issue?
My MPI code runs successfully on single machine.
For MPICH (or any MPI implementation) to work, you need to have passwordless SSH set up. I should also mention that you really shouldn't have to be logged in as root to make this work. It's generally a very bad idea to be logged in as root all of the time.
In /etc/hosts file, add ip address of each server and its hostname.
You should do this for all the servers.
for example:
10.10.0.5 server1
10.10.0.6 server2
10.10.0.7 server3
Just check in /etc/hosts file, not use tab (\t) instead of space to separate between ip address and hostname.
This is wrong:
10.10.0.5 \t server1
This is true:
10.10.0.5 server1
Be careful to not delete or modify existed lines in /etc/hosts file. only add new lines at end of file.
Also, you do not need to disable firewall to fix this issue.

Cannot connect to beaglebone.local

I need to know how to connect to a beaglebone (or beagleboard) with SSH when I plug it into a new network with an ethernet cable like this:
$ ssh root#beaglebone.local
So far I've only been able to access it like this, if I know the IP address:
$ ssh root#<ip_address>
But I don't always know the IP address of the board on new networks so I'm hoping to access it with with a name like: beaglebone.local.
Right now when I try to do this I get this error:
"ssh: Could not resolve hostname beaglebone.local: nodename nor servname provided, or not known"
I checked the hostname and hosts files, and added "127.0.0.1 beaglebone" to the hosts on the beaglebone, but not sure what else I can do?
# cat /etc/hostname
beaglebone
# cat /etc/hosts
127.0.0.1 localhost.localdomain localhost
127.0.0.1 beaglebone
I had a similar issue running my beaglebone on Angstrom-Cloud9-IDE-GNOME-eglibc-ipk-v2012.05-beaglebone-2012.04.22.img.xz. In this distribution, "beaglebone.local" should appear on the network after the system boots.
About 50% of the time after reboot, "beaglebone.local" would not appear on the network (although the bone would be available by IP address). When this happened, "systemctl status avahi-daemon.service" showed that the avahi-daemon failed with "exit code 255". Interestingly, a subsequent "systemctl start avaihi-daemon.service" would always be successful and "beaglebone.local" would appear on the network.
Also "journalctl | grep avahi" returned a single message stating something like "Daemon already runnin gon PID NNN".
So, I "fixed" the problem by adding the line "ExecStartPre=/bin/rm -f /var/run/avahi-daemon/pid" to the [Service] section of /lib/systemd/system/avahi-daemon.service. With this addition, "beaglebone.local" now appears on the network 100% of reboots.
I say "fixed" (i.e., in quotes) because I have not been able to track down the root cause that is leaving around the stray avahi pid file(s) and thus don't have a true fix.
-- Frank
For 'beaglebone.local' to work, your host machine must recognize Zeroconf. The BeagleBone uses Avahi to tell other systems on the LAN that it is there and serving up applications and that it should be called a 'beaglebone'. If there are more than one, the second one is generally called 'beaglebone-2.local'.
I hate answering my own questions. The following hack will work until a better way emerges:
This shell script (where xxx.xxx.xxx is the first three numbers in your computer's IP) will find your beaglebone or beagleboard (that is plugged-into ethernet on a new network with DHCP) by looping through all the ip address on the subnet and attempting to login to each as root. If it finds one then try your password. If it doesn't work just hit enter until the loop starts again. If it doesn't find the board then something else is probably wrong.
for ip in $(seq 1 254); do ssh root#xxx.xxx.xxx.$ip -o ConnectTimeout=5; [ $? -eq 0 ] && echo "xxx.xxx.xxx.$ip UP" || : ; done
UPDATE 1
Today I plugged-in the beaglebone and saw Bonjour recognize that it joined the network. So I tried it and it worked. No idea why it decided to all of the sudden but it did. Strange, but true.
I had this issue quite often with Mac OS X 10.7. But unlike Frank Halasz "systemctl status avahi-daemon.service" shown no failure. And in fact the problem was on the Mac side. Restarting Bonjour with the following commands fixed the issue.
$ sudo launchctl unload /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
$ sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist

Tcl Serial Port fconfigure portability issue

I've got a Tcl/Expect program that reads and writes data to the serial port.
I did all of my development and testing on a Fedora 7 machine, but I'm now trying to run the same code in Ubuntu 8.10, and I'm getting the following error:
spawn: returns {0}
bad option "-mode": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation
while executing
"fconfigure $port -mode 19200,n,8,1"
(file "./scan1.tcl" line 31)
I have no issues in Fedora, just Ubuntu. It would seem that it doesn't like the serial options being given to fconfigure, but I don't know of an alternate way of doing this.
Both machines have Tcl 8.4.
Here's the relevant code snippet:
#Open serial port
set portname "/dev/ttyS0"
spawn -open [set port [open $portname "r+"]];#This is a beast!
fconfigure $port -mode 19200,n,8,1
Does anyone know what's wrong? Thanks for your help!
Some research seems to indicate that the [fconfigure] command doesn't offer the -mode switch when it doesn't recognize the channel in question as being a true serial port (though I don't see this mentioned in the docs). Ultimately, that decision seems to rely on an "isatty()" system call, which is apparently failing to report the channel as a TTY. More info can be found here:
http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/ea0e772c59fa1e52/949c04fe4cebc2a3?q=fconfigure+mode+group:comp.lang.tcl#949c04fe4cebc2a3
According to the above thread, this could be due to a misconfigured Tcl.
Update... I see the serial configuration options (including -mode) are documented with the [open] command. There, it mentions that [fconfigure] can be used to query or set the additional options specific to serial ports. The [fconfigure] docs should probably be updated to reflect that fact also.
Bottom line, Tcl doesn't think your port really is a serial port under Ubuntu, though I don't know why...
Could be a bug. It has been in the past.
http://sourceforge.net/tracker/?func=detail&atid=110894&aid=218617&group_id=10894

Resources