こちらの記事の続きで、QEMUの起動/停止やQEMUモニタの操作と合わせてQEMUとのシリアル通信もPythonで自動化したいと考えています。
そこで、PythonでQEMUとシリアル通信を行う方法を考えた結果をメモします。
QEMUからのシリアル通信デバイスの種類
公式ドキュメントによると、シリアル通信のデバイスとして概ね以下の種類が挙げられます。
pty
/dev/XXX
stdio
これらの方法のうち、
といった理由から、telnetでシリアル通信を行う方法を採用したいと思います。
QEMU側の起動コマンド
qemu-system-aarch64 -cpu cortex-a57 -machine virt -kernel out.img -montor stdio -serial telnet::60000,server,nowait -nographic
telnetの使用するポートはプライベートなものを指定します。
Python側のコード
#!/usr/bin/python3 import telnetlib host = "localhost" port = "60000" tn = telnetlib.Telnet(host=host, port=port) tn.write(b"foo\r\n") print(tn.read_until(b"ok\n", timeout=1).decode('ascii'), end="")
数行でtelnetを通してシリアル通信を行うプログラムが書けました。
なお、telnetの出力を読み出す関数としてread_until()
以外にもread_some()
やread_eager()
、read_lazy()
などがありましたが、
read_some()
は読み出せる文字の数が不安定read_eager()
やread_lazy()
は何故か出力を読み出せなかった(環境の問題?)
といった理由で(少なくとも自分の環境では)使えないので、今回の場合はタイムアウトを指定しつつread_until()
を使うのが適切だと思われます。
参考サイト
QEMU Emulator User Documentation
qemu: pyhtonでゲストとシリアル通信 - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ