在嵌入式开发中,一般都是采用物理机+虚拟机+开发板的架构开发,在前期开发中,为了避免不必要的重复烧写,经常使用tftp的方式将内核或驱动下载到开发板中执行,使用nfs挂在网络文件系统等,这些操作都会用到网络,我也看到网上采用的方式都是使用集线器或者路由器的方式实现物理机、虚拟机、开发板三者互相ping通并且可以同时访问外网的,如果是开发板和电脑直连的方式就会导致不能同时访问外网,主要是不能实现开发板的外网访问,这对一些需要网络调试的调试时很不利的。
好了废话到此为止,以下重点分享一种方案可以在不适用路由器或者集线器的情况下,使用笔记本加开发板直连的方式实现物理机、虚拟机、开发板三者互相ping通并且可以同时访问外网。
物理机:win10企业版(无线网卡+有线网卡)
虚拟机:ubuntu18.4
开发板:100ask-imx6ull开发板
物理机通过wifi无线网络上网
物理机通过有线网络和开发板直连
虚拟机通过网卡1使用nat方式上网;通过网卡2桥接到物理机有线网络
虚拟机通过网卡2使用桥接方式
物理机无线网卡:通过路由器自动获取一个ip地址(不重要,能上网就行)
物理机有线网卡:自定义一个内网ip段即可如 192.168.8.8
虚拟机网卡1:通过nat方式上网,也是一个内网ip,和虚拟网卡VMware Network Adapter VMnet8有关,例如我的是 192.168.10.100
虚拟机网卡2:通过桥接模式上网,桥接到物理机的有线网卡上,ip设置与物理网卡同网段,因为后期用于网关功能,因此我设置为 192.168.8.1
开发板有线网卡:和物理机有线网卡直连,需要设置和物理机有线网卡同网段,因此设置为192.168.8.100
网卡 | IP |
---|---|
物理机无线网卡 (wlan) | 192.168.1.100 |
物理机有线网卡 (以太网) | 192.168.8.8 |
虚拟机网卡1(ens33) | 192.168.10.100 |
虚拟机网卡2 (ens38) | 192.168.8.1 |
开发板有线网卡(eth0) | 192.168.8.100 |
这里面提到的虚拟机两种上网方式,桥接和nat,可以参考文章最后章节的补充内容做适当了解或者百度搜索相关词条做具体详细了解。
快速传送到桥接和nat转换介绍
通过以上表格中ip地址分配应该可以看出以太网、ens38、eth0之间在同一个网段,他们之间ping通应该是理所应当的,物理机通过无线网卡上网,并且虚拟机可以通过nat方式使用ens33上网,这些都是基础操作,基本上都是很容易实现的,关键就在于如何让开发板也可以上网。
目前其实真正具备上网能力的就是wlan这个无线网卡连接到了路由器,我们来看一下虚拟机怎么上网的,虚拟机配置了两种模式,桥接和nat,其中桥接主要是为了和物理机开发板相互ping通,这一条网络通路并不能实现上网,那么真正可以上网的是ens33这个通过nat方式上网的网卡,其实就是把物理机当做路由器,网络流量走waln无线网卡转发,那么我们就可以借助这个思路,让我们的ens38这个网卡做网关,开发板流量到ens38后,经过ens33这块可以上网的网卡转发,这样就实现了开发板也可以上网。这里简单描述了一下原理,具体深究需要进一步了解nat转发、网关、路由等知识。
前面介绍了实验环境和原理的东西,接下来是物理机、开发板、虚拟机配置的具体过程。
该部分不需要特别的配置,只需要保证连接路由器可以正常上网就可以了
将物理机的有线网卡配置成固定ip,当然如果使用有线网络上网的话记得还改为自动ip地址,否则有可能上不了网。
首先关闭虚拟机,执行编辑虚拟机设置—>添加—>网络适配器—>完成之后就会看到新添加了一个虚拟网卡,实际上虚拟机是可以添加任意多得虚拟网卡的,目前两个就够用了。
然后一个设置为nat,一个设置为桥接。设置完毕,启动虚拟机。
对于虚拟机来说,我习惯都使用静态ip地址,这样以后ssh、nfs等操作都比较方便,否则ip地址变来变去着实麻烦。
打开终端执行sudo vim /etc/network/interfaces
修改interfaces文件来配置ip地址
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet static
address 192.168.10.100
gateway 192.168.10.2
netmask 255.255.255.0
auto ens38
iface ens38 inet static
address 192.168.8.1
gateway 192.168.10.100
netmask 255.255.255.0
添加DNS配置,ubuntu新版本的dns配置不能再编辑 /etc/resolv.conf
这个经典的配置文件了,不同的版本可能有不同的配置文件路径
执行 cat /etc/resolv.conf
可以看到如下介绍,这是一个动态创建的文件,不能编辑,重启会被覆盖,当然临时写入dns配置还是可以生效的,就是重启就没有了,这肯定是我们不希望的,那么我们参照文件中第一行说man手册中有介绍
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
......
......
我们尝试打开man手册查看一下看能不能找到相关信息
执行man systemd-resolved
可以看到配置文件在/etc/systemd/resolved.conf
这个位置
既然知道了配置文件位置,直接执行sudo vim /etc/systemd/resolved.conf
打开文件进行配置,去掉DNS前面的#取消注释,添加DNS即可
[Resolve]
DNS=114.114.114.114
DNS=8.8.8.8
DNS=8.8.4.4
修改完之后重启虚拟机
reboot
执行ifconfig
查看一下ip地址
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.100 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::20c:29ff:feb7:ec8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b7:0e:c8 txqueuelen 1000 (Ethernet)
RX packets 626 bytes 551668 (551.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 514 bytes 76435 (76.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens38: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.1 netmask 255.255.255.0 broadcast 192.168.8.255
inet6 fe80::20c:29ff:feb7:ed2 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b7:0e:d2 txqueuelen 1000 (Ethernet)
RX packets 117 bytes 56484 (56.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 70 bytes 7170 (7.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
执行ping www.baidu.com
查看网络是否通畅
book@100ask:~$ ping www.baidu.com
PING www.a.shifen.com (182.61.200.6) 56(84) bytes of data.
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=1 ttl=128 time=33.6 ms
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=2 ttl=128 time=32.0 ms
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=3 ttl=128 time=32.7 ms
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=4 ttl=128 time=33.9 ms
64 bytes from 182.61.200.6 (182.61.200.6): icmp_seq=5 ttl=128 time=35.0 ms
^C
--- www.a.shifen.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4007ms
rtt min/avg/max/mdev = 32.002/33.492/35.087/1.067 ms
至此虚拟机ip地址和上网环境配置完成,至于其他版本的ubuntu如果该DNS配置方式不适合可以自行百度解决,最终可以实现对外网的ping通即可
这里涉及Linux iptables
中NAT网络地址转换的用法可以参考文章最后章节的补充内容做适当了解或者百度搜索相关词条做具体详细了解。
快速传送到 iptables nat转换介绍
执行 vim /etc/sysctl.conf
修改配置文件将net.ipv4.ip_forward修改为1打开网络转发,开启路由功能。
执行sudo iptables -t nat -A POSTROUTING -o ens33 -s 192.168.8.0/24 -j MASQUERADE
将192.168.0/24这个网段的流量通过nat网络地址转换通过ens33转发出去。这是整个流程的核心。
然后执行sudo iptables -t nat -nL
查看nat转发表
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 192.168.8.0/24 0.0.0.0/0
如果看到以上输出证明nat转发建立成功。
至此虚拟机配置结束,接下来处理开发板的网络配置。
进入开发板终端直接执行ifconfig eth0 192.168.8.100
将开发板ip地址配置的和物理机有线网卡和虚拟机桥接网卡通ip段即可
然后添加默认网关,前面已经介绍了,我们准备使用虚拟机的桥接网卡ens38作为网关,流量也是从这里通过nat转换经过ens33转发出去的
执行route add default gw 192.168.8.1
设置开发板的默认网关
如果不出意外的话开发板就可以ping通外网了。
ping一下国内经典的DNS试试,执行ping 114.114.114.114
得到以下输出
[root@imx6ull:~]# ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=127 time=5.688 ms
64 bytes from 114.114.114.114: seq=1 ttl=127 time=5.214 ms
64 bytes from 114.114.114.114: seq=2 ttl=127 time=4.708 ms
64 bytes from 114.114.114.114: seq=3 ttl=127 time=5.136 ms
^C
--- 114.114.114.114 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 4.708/5.186/5.688 ms
可以看到已经可以访问外网了,但是还需要解决域名的问题,此事就是可以直接配置经典额dns配置文件/etc/resolv.conf
了。
执行vim /etc/resolv.conf
打开配置文件,添加以下配置:
nameserver 114.114.114.114
nameserver 8.8.8.8
对于DNS配置各个虚拟机开发板各不相同,还行读者自行解决。
执行ping www.baidu.com
做最后验证,看到以下输出证明大功告成
[root@imx6ull:~]# ping www.baidu.com
PING www.baidu.com (182.61.200.6): 56 data bytes
64 bytes from 182.61.200.6: seq=0 ttl=127 time=34.993 ms
64 bytes from 182.61.200.6: seq=1 ttl=127 time=35.708 ms
64 bytes from 182.61.200.6: seq=2 ttl=127 time=35.294 ms
64 bytes from 182.61.200.6: seq=3 ttl=127 time=34.572 ms
64 bytes from 182.61.200.6: seq=4 ttl=127 time=33.783 ms
^C
--- www.baidu.com ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 33.783/34.870/35.708 ms
[root@imx6ull:~]# ifconfig
eth0 Link encap:Ethernet HWaddr 46:11:34:E4:25:B3
inet addr:192.168.8.100 Bcast:192.168.8.255 Mask:255.255.255.0
inet6 addr: fe80::4411:34ff:fee4:25b3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:275 errors:0 dropped:0 overruns:0 frame:0
TX packets:575 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:32401 (31.6 KiB) TX bytes:291945 (285.1 KiB)
eth1 Link encap:Ethernet HWaddr 5A:A8:E4:44:D6:18
inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:5636 errors:0 dropped:0 overruns:0 frame:0
TX packets:5636 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:338766 (330.8 KiB) TX bytes:338766 (330.8 KiB)
[root@imx6ull:~]# ping 192.168.8.8
PING 192.168.8.8 (192.168.8.8): 56 data bytes
64 bytes from 192.168.8.8: seq=0 ttl=128 time=3.326 ms
64 bytes from 192.168.8.8: seq=1 ttl=128 time=2.063 ms
64 bytes from 192.168.8.8: seq=2 ttl=128 time=2.293 ms
64 bytes from 192.168.8.8: seq=3 ttl=128 time=1.849 ms
^C
--- 192.168.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 1.849/2.382/3.326 ms
[root@imx6ull:~]# ping 192.168.8.1
PING 192.168.8.1 (192.168.8.1): 56 data bytes
64 bytes from 192.168.8.1: seq=0 ttl=64 time=2.366 ms
64 bytes from 192.168.8.1: seq=1 ttl=64 time=2.111 ms
64 bytes from 192.168.8.1: seq=2 ttl=64 time=1.992 ms
64 bytes from 192.168.8.1: seq=3 ttl=64 time=1.975 ms
^C
--- 192.168.8.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 1.975/2.111/2.366 ms
[root@imx6ull:~]# ping 192.168.10.100
PING 192.168.10.100 (192.168.10.100): 56 data bytes
64 bytes from 192.168.10.100: seq=0 ttl=64 time=2.781 ms
64 bytes from 192.168.10.100: seq=1 ttl=64 time=2.881 ms
64 bytes from 192.168.10.100: seq=2 ttl=64 time=2.361 ms
^C
--- 192.168.10.100 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 2.361/2.674/2.881 ms
[root@imx6ull:~]# ping www.baidu.com
PING www.baidu.com (182.61.200.7): 56 data bytes
64 bytes from 182.61.200.7: seq=0 ttl=127 time=35.189 ms
64 bytes from 182.61.200.7: seq=1 ttl=127 time=36.219 ms
64 bytes from 182.61.200.7: seq=2 ttl=127 time=34.149 ms
64 bytes from 182.61.200.7: seq=3 ttl=127 time=34.871 ms
^C
--- www.baidu.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 34.149/35.107/36.219 ms
Microsoft Windows [版本 10.0.18362.657]
(c) 2019 Microsoft Corporation。保留所有权利。
C:\Users\shuai>ping 192.168.8.100
正在 Ping 192.168.8.100 具有 32 字节的数据:
来自 192.168.8.100 的回复: 字节=32 时间=1ms TTL=64
来自 192.168.8.100 的回复: 字节=32 时间=1ms TTL=64
来自 192.168.8.100 的回复: 字节=32 时间=1ms TTL=64
来自 192.168.8.100 的回复: 字节=32 时间=1ms TTL=64
192.168.8.100 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 1ms,最长 = 1ms,平均 = 1ms
C:\Users\shuai>ping 192.168.8.1
正在 Ping 192.168.8.1 具有 32 字节的数据:
来自 192.168.8.1 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.8.1 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.8.1 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.8.1 的回复: 字节=32 时间<1ms TTL=64
192.168.8.1 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
C:\Users\shuai>ping 192.168.10.100
正在 Ping 192.168.10.100 具有 32 字节的数据:
来自 192.168.10.100 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.10.100 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.10.100 的回复: 字节=32 时间=1ms TTL=64
来自 192.168.10.100 的回复: 字节=32 时间<1ms TTL=64
192.168.10.100 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 1ms,平均 = 0ms
C:\Users\shuai>ping www.baidu.com
正在 Ping www.a.shifen.com [182.61.200.6] 具有 32 字节的数据:
来自 182.61.200.6 的回复: 字节=32 时间=31ms TTL=51
来自 182.61.200.6 的回复: 字节=32 时间=32ms TTL=51
来自 182.61.200.6 的回复: 字节=32 时间=31ms TTL=51
来自 182.61.200.6 的回复: 字节=32 时间=30ms TTL=51
182.61.200.6 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 30ms,最长 = 32ms,平均 = 31ms
book@100ask:~$ ping 192.168.8.8
PING 192.168.8.8 (192.168.8.8) 56(84) bytes of data.
64 bytes from 192.168.8.8: icmp_seq=1 ttl=128 time=1.27 ms
64 bytes from 192.168.8.8: icmp_seq=2 ttl=128 time=0.193 ms
64 bytes from 192.168.8.8: icmp_seq=3 ttl=128 time=0.203 ms
64 bytes from 192.168.8.8: icmp_seq=4 ttl=128 time=0.240 ms
^C
--- 192.168.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3056ms
rtt min/avg/max/mdev = 0.193/0.477/1.275/0.461 ms
book@100ask:~$ ping 192.168.8.100
PING 192.168.8.100 (192.168.8.100) 56(84) bytes of data.
64 bytes from 192.168.8.100: icmp_seq=1 ttl=64 time=1.63 ms
64 bytes from 192.168.8.100: icmp_seq=2 ttl=64 time=1.61 ms
64 bytes from 192.168.8.100: icmp_seq=3 ttl=64 time=1.90 ms
64 bytes from 192.168.8.100: icmp_seq=4 ttl=64 time=1.67 ms
^C
--- 192.168.8.100 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.615/1.707/1.906/0.123 ms
book@100ask:~$ ping www.baidu.com
PING www.a.shifen.com (182.61.200.7) 56(84) bytes of data.
64 bytes from 182.61.200.7 (182.61.200.7): icmp_seq=1 ttl=128 time=32.6 ms
64 bytes from 182.61.200.7 (182.61.200.7): icmp_seq=2 ttl=128 time=32.3 ms
64 bytes from 182.61.200.7 (182.61.200.7): icmp_seq=3 ttl=128 time=30.9 ms
64 bytes from 182.61.200.7 (182.61.200.7): icmp_seq=4 ttl=128 time=32.5 ms
^C
--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 30.994/32.149/32.669/0.699 ms
通过以上验证可以看到确实实现了开发板直连的方式实现物理机、虚拟机、开发板三者互相ping通并且可以同时访问外网。
桥接模式
桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下,类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰。在桥接模式下,虚拟机ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致。其网络结构如下图所示:
nat模式
如果网络ip资源紧缺,但是又希望你的虚拟机能够联网,这时候NAT模式是最好的选择。NAT模式借助虚拟NAT设备和虚拟DHCP服务器,使得虚拟机可以联网。其网络结构如下图所示:
在NAT模式中,主机网卡直接与虚拟NAT设备相连,然后虚拟NAT设备与虚拟DHCP服务器一起连接在虚拟交换机VMnet8上,这样就实现了虚拟机联网。那么我们会觉得很奇怪,为什么需要虚拟网卡VMware Network Adapter VMnet8呢?原来我们的VMware Network Adapter VMnet8虚拟网卡主要是为了实现主机与虚拟机之间的通信。
本小节参考来源:https://blog.csdn.net/zkuncn/article/details/78452098
原理介绍
iptables在linux中常常被用于防火墙来管理入站出站规则,但是它还有一个作用就是可以做nat网络地址转换,本文中主要使用的也是后者nat地址转换的功能。
SNAT即源地址转换:
能够让多个内网用户通过一个外网地址上网,解决了IP资源匮乏的问题。一个无线路由器也就使用此技术。
由上图可知,需要将192.168.10.10转换为111.196.211.212,iptables命令如下:
iptables –t nat –A POSTROUTING –s 192.168.10.10 –o eth1 –j SNAT --to-source 111.196.221.212
外网IP地址不稳定的情况即可使用MASQUERADE(动态伪装),能够自动的寻找外网地址并改为当前正确的外网IP地址
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
本文中就是使用的这个方式将ens38的网络流量通过nat地址转换经ens33网卡发出去实现上网。
DNAT即目地地址转换:
则能够让外网用户访问局域网内不同的服务器。(相当于SNAT的反向代理)
由上图可知,目标地址192.168.10.6在路由前就转换成61.240.149.149,需在网关上运行iptables命令如下:
iptables –t nat –A PREROUTING –i eth1 –d 61.240.149.149 –p tcp –dport 80 –j DNAT --to-destination 192.168.10.6:80
eth1网口传入,且想要使用 port 80 的服务时,将该封包重新传导到 192.168.1.210:80 的 IP 及 port 上面,可以同时修改 IP 与 port。此为地址映射与端口转换。
还可以使用REDIRECT单独进行端口转换
例:将 80 端口的封包转递到 8080端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
本小节参考来源:https://www.cnblogs.com/whych/p/9147900.html
虚拟机开启网络转发
按照上面具体实现章节操作一般不会出现什么问题,如果遇到问题,可以按照以下表格常见问题分步调试。
ping报错 | 可能原因 |
---|---|
网络不可达 | 一般是网关没有设置或者设置错误 |
没有返回 | 检查路由表和nat转发是否正常 |
ping ip不能ping域名 | DNS设置问题 |
不能ping同物理机 | 检查windows防火墙 |
最后希望大家开发愉快!!!