如何在QEMU内部路由TCP端口/套接字?

3
我正在尝试运行FreeRTOS+TCP demo(版本10.1.1):
这段代码是为Windows模拟器编写的,但我正在尝试将其针对由QEMU(版本4.2.0)模拟的Xilinx Zynq进行目标化。主机机器是Ubuntu 16.04。存在一个网络接口端口,用于FreeRTOS+TCPTCP部分,因此应该是可行的。
修改演示的一个明显的修改是更改消息打印方式,并删除对Windows Sleep函数的调用。此外,我正在使用ARM semihosting来查看打印语句的输出。
除了这些更改,我需要对命令行调用进行哪些更改?演示创建了一个TCP回显服务器和客户端。如果将它们绑定在一起,那么不需要将流量发送到主机,对吗?为了使其工作,我需要做些特殊的事情吗?我对网络方面没有太多经验。
由于这在技术上是一个裸金属应用程序,因此类似-nic user,hostfwd = tcp :: 5022-:22的CLI选项会发出警告qemu-system-arm:warning:nic cadence_gem.1 has no peer.(在How to replace 'qemu-system -redir' command argument?中找到)。
如果我想在主机和客户机之间发送流量(例如使用ncat回声服务器,而不是在FreeRTOS中),我该如何做?
这里有一个相关的问题,没有解决方案: 在QEMU中运行LWIP TCP/IP堆栈 当前的命令行参数:
qemu-system-arm -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 512M -cpu cortex-a9 -nic user,hostfwd=tcp::12346-:7 -kernel build/rtos_demo_tcp/rtos_demo_tcp.elf

当前输出(我启用了额外的调试信息):
qemu-system-arm: warning: nic cadence_gem.1 has no peer
Seed for randomiser: 1591112953
Random numbers: 00001294 00001925 000022D0 00005CC3
FreeRTOS_IPInit
vTaskStartScheduler
prvIPTask started
Network buffers: 30 lowest 30


IP Address: 10.2.118.223
Subnet Mask: 255.255.255.0
Gateway Address: 10.2.118.1
DNS Server Address: 208.67.222.222


Socket 7 -> 0ip:0 State eCLOSED->eTCP_LISTEN

接下来的部分会不断重复,每次使用不同的套接字号。
FreeRTOS_connect: 14207 to a0276dfip:7
Socket 14207 -> a0276dfip:7 State eCLOSED->eCONNECT_SYN
ARP for a0276dfip (using a0276dfip): rc=0 00:00:00 00:00:00
Network buffers: 30 lowest 29
Connect[a0276dfip:7]: next timeout 1: 500 ms
ARP for a0276dfip (using a0276dfip): rc=0 00:00:00 00:00:00
Connect[a0276dfip:7]: next timeout 2: 500 ms
ARP for a0276dfip (using a0276dfip): rc=0 00:00:00 00:00:00
Connect[a0276dfip:7]: next timeout 3: 500 ms
Connect: giving up a0276dfip:7
Socket 14207 -> a0276dfip:7 State eCONNECT_SYN->eCLOSE_WAIT
FreeRTOS_closesocket[14207 to a0276dfip:7]: buffers 30 socks 1

摘要:我该如何更改我的 QEMU 调用方式,以便 TCP 客户端和服务器可以彼此连接?

1个回答

3
我建议尝试在QEMU网络指南中列举的所有选项:
- SLIRP-netdev user,id = mynet0,net = 192.168.76.0/24,dhcpstart = 192.168.76.9
- TAP-netdev tap,id = mynet0
- SOCKET-netdev socket,id = mynet0,listen =:1234-netdev socket,id = mynet0,connect =:1234

指南中还有更多内容。您可能还要考虑的是,直接从您关心的虚拟机进行端口转发可能会很困难,而将该虚拟机连接到另一个虚拟机并从第二个虚拟机向主机进行端口转发可能会更容易一些。

有点奇怪,但这是我以前需要做的事情。在两个虚拟机之间进行通信,我发现使用sockets是最好的方法。它们的工作方式有点像“虚拟交叉线缆”。
这种虚拟机对虚拟机的方法允许您只需在每个虚拟机上设置相应的静态IP和子网,然后ncat就可以在它们之间工作。摒弃所有复杂的DHCP服务器和任何端口转发的复杂性。

感谢您的建议。我编写了两个版本的代码,一个运行服务器任务,另一个运行客户端任务。我已经更改了qemu调用的网络部分: -nic socket,id=n1,mac=00:17:34:51:68:65,listen=:2222-nic socket,id=n2,mac=00:17:34:51:68:66,connect=127.0.0.1:2222。 现在客户端任务比之前有更多进展,但服务器仍然无法连接。 我会继续努力解决问题,但如果您有其他建议,我将不胜感激。 - thatjames
1
继续努力。在使用QEMU进行开发时,总会有“我在QEMU命令中做错了什么吗?”和“我在虚拟机中做错了什么吗?”的疑问。最好的方法是首先确定并对如何虚拟化您的环境充满信心。我相信您已经正确地设置了QEMU命令。现在是时候提出一个网络问题了。 - Lenna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接