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

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.

Related

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.

Serial communication between QEMU host and guest

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.

how to redirect the output of serial console (e.g. /dev/ttyS0) to a buffer or file

Is it possible to pipe serial console output to a file or a buffer or some virtual or pseudo device (in /dev)?
The Kernel command line has in startup at this point "console=null,115200".
(Normally it has "console=ttyS0,115200" - my requirement is: if "console=null,115200", should the output go to some other place than ttyS0, e.g. a virtual or pseudo device or to a file/buffer)
Maybe somebody know if there is good solution available?
Thanks a lot in advance!
There are two ways that I am aware of :-
First way :-
get ttylog from sourceforge :-
http://sourceforge.net/projects/ttylog/files/latest/download
Fire the below command:-
nohup ttylog -b 115200 -d /dev/ttyS0 > log.txt
this will then show you the PID of the process that is running, you now need to disown that PID so it doesn't get killed when you log out. Note that 115200 is the serial port speed/baud rate you configured grub for on the box you are monitoring.
Second way :-
Setup a serial console from system under test to some other linux/windows box. In case of linux install minicom and set minicom to listen on the serial port define in grub of system under test. Save that as dfl. You are good to go for more info :-
https://www.kernel.org/doc/Documentation/serial-console.txt

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