[QEMU]OpenWrt

QEMU 是一个开源处理器仿真器(和虚拟器)。 本文档介绍如何在QEMU中运行OpenWrt。

不同的网卡会极大地影响性能。
ne2k_pci:0.0-31.3 sec 14.6 MBytes 3.92 Mbits/sec
pcnet: 0.0-30.0 sec 2.38 GBytes 682 Mbits/sec
e1000: 0.0-30.0 sec 6.23 GBytes 1.79 Gbits/sec
vmxnet3: 0.0-30.0 sec 8.67 GBytes 2.48 Gbits/sec
virtio-net-pci: 0.0-30.0 sec 44.6 GBytes 12.8 Gbits/sec

OpenWrt in QEMU aarch64
启动命令
qemu-system-aarch64 -m 1024 -smp 2 -cpu cortex-a57 -M virt -nographic -kernel openwrt-19.07.3-armvirt-64-Image-initramfs -drive if=none,file=disk.img,id=hd0 -device virtio-blk-device,drive=hd0
下面是网络接口和存储的示例:
qemu-system-aarch64 --enable-kvm -M virt -nographic -nodefaults -m 128 -cpu host -smp 2 -kernel openwrt-armvirt-64-Image -append "root=fe00" -blockdev driver=raw,node-name=hd0,cache.direct=on,file.driver=file,file.filename=openwrt-armvirt-64-root.ext4 -device virtio-blk-pci,drive=hd0 -netdev type=tap,id=nic1,ifname=kvm0,script=no,downscript=no -device virtio-net-pci,disable-legacy=on,disable-modern=off,netdev=nic1,mac=ba:ad:1d:ea:01:02 -device qemu-xhci,id=xhci,p2=8,p3=8 -device usb-host,vendorid=0x7392,productid=0x7822
没有 initrd 的内核将自动尝试挂载 ext4 分区,但必须用参数告诉它在哪里(如果您不指定,内核将列出可用的块设备并重新启动)
-append “root=fe00”
-blockdev
其次是在 qemu 中指定块设备的新方法 - 我可以使用 -drive,但我从其他地方复制了大部分配置-device
-netdev
将虚拟网卡绑定到主机分流器接口 kvm0,应在启动 qemu 之前创建;如果您需要多个网卡,只需复制 Andlines 并调整 ifname(点击主机上的设备)、ID(设备 ID,将 -netDev 和 -device 连接在一起)和 MAC 地址-netdev
-device virtion-net-pci
最后两行添加 USB3 控制器并将物理 USB WiFi 加密狗连接到虚拟机
OpenWrt in QEMU aarch64 on Apple Silicon (MacOS, M1+ hardware, Native)
非持久(使用openwrt-armvirt-64-Image-initramfs)
qemu-system-aarch64 -m 1024 -smp 2 -cpu host -M virt,highmem=off \
-nographic \
-accel hvf \
-kernel openwrt-armvirt-64-Image-initramfs \
-device virtio-net,netdev=net0 -netdev user,id=net0,net=192.168.1.0/24,hostfwd=tcp:127.0.0.1:1122-192.168.1.1:22 \
-device virtio-net,netdev=net1 -netdev user,id=net1,net=192.0.2.0/24
持久(带有openwrt-armvirt-64-image和openwrt-armvirt-64-rootfs-squashfs.img)
qemu-system-aarch64 -m 1024 -smp 2 -cpu host -M virt,highmem=off \
-nographic \
-accel hvf \
-kernel openwrt-armvirt-64-Image \
-drive file=openwrt-armvirt-64-rootfs-squashfs.img,format=raw,if=virtio \
-append root=/dev/vda \
-device virtio-net,netdev=net0 -netdev user,id=net0,net=192.168.1.0/24,hostfwd=tcp:127.0.0.1:1122-192.168.1.1:22 \
-device virtio-net,netdev=net1 -netdev user,id=net1,net=192.0.2.0/24
eth0 (局域网))
eth1 (广域网)
qemu dhcp-server 将为 OpenWrt 主机分配 192.0.2.15IP地址,并提供IPv4互联网接入
要从主机通过SSH访问OpenWrt:
ssh -p1122 root@127.0.0.1
可以通过IP192.168.1.2(通过 eth0)或 192.0.2.2(通过 eth1)从 OpenWrt 来宾连接到主机
OpenWrt in QEMU x86-64
默认情况下,x86-64 目标支持 ESXi 映像。 引导 VMDK/VDI 映像可能不适用于较新的 QEMU 版本。
带有“-HAD”开关的 IMG/VDI/VMDK 不适用于 QEMU 2.x。
PC-Q35-2.0 / Q35模拟不同的机器。 使用新语法(no -had , -net),IMG / VDI / VMDK 在这里工作。 某些模拟网卡可能存在性能问题。
特征:
2 个硬盘(1 个 OpenWrt 映像,1 个数据)
每总线 1 个驱动器,6 个总线可用(直到 IDE.5)
2 个网卡:1 个桥接到主机(需要更高的权限)和 1 个“用户”(默认,NAT10.x.x.x)
qemu-system-x86_64 \
-enable-kvm \
-M pc-q35-2.0 \
-drive file=openwrt-x86_64-combined-ext4.vdi,id=d0,if=none \
-device ide-hd,drive=d0,bus=ide.0 \
-drive file=data.qcow2,id=d1,if=none \
-device ide-hd,drive=d1,bus=ide.1 \
-soundhw ac97 \
-netdev bridge,br=virbr0,id=hn0 \
-device e1000,netdev=hn0,id=nic1 \
-netdev user,id=hn1 \
-device e1000,netdev=hn1,id=nic2
qemu-system-x86_64 -M q35 \
-drive file=openwrt-x86_64-combined-ext4.img,id=d0,if=none,bus=0,unit=0 \
-device ide-hd,drive=d0,bus=ide.0
UEFI 固件需要安装 ovmf 软件包。
qemu-system-x86_64 \
-enable-kvm -m 1G -drive if=pflash,format=raw,readonly,file=/usr/share/edk2-ovmf/x64/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=my_uefi_vars.fd
提供对OpenWrt的互联网访问
QEMU 的默认网络模式是“用户模式网络堆栈”。
在此模式下,充当出站TCP/UDP连接的代理。 它还为模拟系统提供DHCP和DNS服务。qemu
要提供对模拟OpenWrt系统的互联网访问,请使用(该示例使用armvirt系统,请根据您的设置进行调整):
qemu-system-arm -net nic,vlan=0 -net nic,vlan=1 -net user,vlan=1 \
-nographic -M virt -m 64 -kernel lede-17.01.0-r3205-59508e3-armvirt-zImage-initramfs
在这里,我们在模拟的OpenWrt系统中设置了两个网卡:
eth0
,在OpenWrt中用作LAN(此处未连接到任何内容)eth1
,在OpenWrt中用作WAN,并连接到qemu,它将代理所有TCP / UDP连接到互联网
OpenWrt系统应该同时打开IPv4和IPv6(通过DHCP / DHCPv6)。 范围将是 10.0.2.0/24 和 fec0::/64。eth1
在OpenWrt中提供对LUCI的访问
LUCI是OpenWrt使用的Web UI。 如果您想检查LUCI的工作原理或使用LUCI应用程序进行探索,则此设置适合您。 (该示例使用Armvirt系统,请根据您的设置进行调整)
注意:此设置需要一些权限(在 Linux 下),因此在 Linux 下运行它更容易CAP_NET_ADMIN
CAP_MKNOD
sudo
保存脚本和编辑变量以反映您的 OpenWrt 版本,然后在IMAGE
sudo
#!/bin/sh
IMAGE=lede-17.01.0-r3205-59508e3-armvirt-zImage-initramfs
LAN=ledetap0
# create tap interface which will be connected to OpenWrt LAN NIC
ip tuntap add mode tap $LAN
ip link set dev $LAN up
# configure interface with static
ip to avoid overlapping routes
ip addr add 192.168.1.101/24 dev $LAN
qemu-system-arm \
-device virtio-net-pci,netdev=lan \
-netdev tap,id=lan,ifname=$LAN,script=no,downscript=no \
-device virtio-net-pci,netdev=wan \
-netdev user,id=wan \
-M virt -nographic -m 64 -kernel $IMAGE
# cleanup, delete tap interface created earlier
ip addr flush dev $LAN
ip link set dev $LAN down
ip tuntap del mode tap dev $LAN
网络的工作原理:
eth0
,在OpenWrt中用作LAN,并连接到主机系统(静态地址),提供对LUCI的访问ledetap0
192.168.1.101/24
http://192.168.1.1
eth1
,在OpenWrt中用作WAN,并连接到qemu,它将代理所有TCP / UDP连接到互联网
主机的转发端口
如果在嵌入式系统上配置了不能使用的 NIC,则可以通过在选项中使用转发(高)端口从主机访问它们。-device
-nic
hostfwd=hostip:hostport-guestip:guestport
例如,要从客户机系统上的主机访问 SSH,可以使用:ssh root@127.1 -p 1122
malta-be
qemu-system-mips -M malta -nographic -hda openwrt-malta-be-rootfs-ext4.img \
-kernel openwrt-malta-be-vmlinux.elf -append 'root=/dev/sda console=ttyS0' \
-nic hostfwd=tcp::1122-:22
如果网络适配器是WAN接口,则必须在来宾中添加防火墙规则以允许SSH:
uci -q delete firewall.ssh
uci set firewall.ssh="rule"
uci set firewall.ssh.name="Allow-SSH"
uci set firewall.ssh.src="wan"
uci set firewall.ssh.dest_port="22"
uci set firewall.ssh.proto="tcp"
uci set firewall.ssh.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart
使用 KVM igb 网络接口
(摘自菲利普·普林德维尔的邮件列表帖子)
在我的 Centos 7.4 KVM 主机上,我做到了:
要为每个网卡预配 10 个 VF,请执行以下操作:
cat << EOF > /etc/modprobe.d/sr-iov.conf
# for SR-IOV support
options igb max_vfs=10
EOF
这将在下次重新启动后生效。 或者通过卸载并重新加载IGB模块。
为要支持虚拟化的每个 NIC 创建 XML 文件:
# cat << EOF > /tmp/hostdev-net0.xml
<network>
<name>hostdev-net0</name>
<uuid>$(uuidgen)</uuid>
<forward mode='hostdev' managed='yes'>
<pf dev='eno1'/>
</forward>
</network>EOF cat << EOF > /tmp/hostdev-net1.xml
<network>
<name>hostdev-net1</name>
<uuid>$(uuidgen)</uuid>
<forward mode='hostdev' managed='yes'>
<pf dev='eno2'/>
</forward>
</network>
EOF
virsh net-destroy default
virsh net-define /tmp/hostdev-net0.xml
virsh net-autostart hostdev-net0
virsh net-define /tmp/hostdev-net1.xml
virsh net-autostart hostdev-net1
创建 VF 接口池。
然后,为了向 VM 添加接口
# cat << EOF > /tmp/new-interface-0.1.xml
<interface type='network'>
<mac address='52:54:00:0d:84:f4'/>
<source network='hostdev-net0'/>
<address type='pci' domain='0x0000' bus='0x07' slot='0x10' function='0x0'/>
</interface>
EOF
# Where the ‘0d:84:f4’ is 3 unique bytes
dd status=none bs=1 count=3 if=/dev/urandom | hexdump -e '/1 "%x"\n'
virsh attach-device my-machine-1 /tmp/new-interface-0.1.xml
使用 KVM 加速
这将要快得多,但只有在 CPU 的架构与目标映像相同时才有效(此处为 ARM cortex-a15)。
qemu-system-arm -nographic -M virt,accel=kvm -cpu host -m 64 -kernel openwrt-armvirt-zImage-initramfs
使用单独的根引导
qemu-system-arm -nographic -M virt -m 64 \
-kernel openwrt-armvirt-zImage \
-drive file=openwrt-armvirt-root.ext4,format=raw,if=virtio \
-append 'root=/dev/vda rootwait'
使用本地目录作为 rootfs 引导
qemu-system-arm -nographic -M virt -m 64 -kernel openwrt-armvirt-zImage \
-fsdev local,id=rootdev,path=root-armvirt/,security_model=none \
-device virtio-9p-pci,fsdev=rootdev,mount_tag=/dev/root \
-append 'rootflags=trans=virtio,version=9p2000.L,cache=loose rootfstype=9p'
使用 kvmtool 运行
# start a named machine
lkvm run -k openwrt-armvirt-zImage -i openwrt-armvirt-rootfs.cpio --name armvirt0
# start with virtio-9p rootfs
lkvm run -k openwrt-armvirt-zImage -d root-armvirt/
# stop "armvirt0"
lkvm stop --name armvirt0
# stop all
lkvm stop --all
转载于
[OpenWrt Wiki]OpenWrt in QEMU