[QEMU]OpenWrt

QEMU 是一個開源處理器仿真器(和虛擬器)。 本文檔介紹如何在QEMU中運行OpenWrt。

不同的網(wǎng)卡會極大地影響性能。
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
下面是網(wǎng)絡(luò)接口和存儲的示例:
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 的內(nèi)核將自動嘗試掛載 ext4 分區(qū),但必須用參數(shù)告訴它在哪里(如果您不指定,內(nèi)核將列出可用的塊設(shè)備并重新啟動)
-append “root=fe00”
-blockdev
其次是在 qemu 中指定塊設(shè)備的新方法 - 我可以使用 -drive,但我從其他地方復(fù)制了大部分配置-device
-netdev
將虛擬網(wǎng)卡綁定到主機分流器接口 kvm0,應(yīng)在啟動 qemu 之前創(chuàng)建;如果您需要多個網(wǎng)卡,只需復(fù)制 Andlines 并調(diào)整 ifname(點擊主機上的設(shè)備)、ID(設(shè)備 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 (局域網(wǎng)))
eth1 (廣域網(wǎng))
qemu dhcp-server 將為 OpenWrt 主機分配 192.0.2.15IP地址,并提供IPv4互聯(lián)網(wǎng)接入
要從主機通過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 映像。 引導(dǎo) VMDK/VDI 映像可能不適用于較新的 QEMU 版本。
帶有“-HAD”開關(guān)的 IMG/VDI/VMDK 不適用于 QEMU 2.x。
PC-Q35-2.0 / Q35模擬不同的機器。 使用新語法(no -had , -net),IMG / VDI / VMDK 在這里工作。 某些模擬網(wǎng)卡可能存在性能問題。
特征:
2 個硬盤(1 個 OpenWrt 映像,1 個數(shù)據(jù))
每總線 1 個驅(qū)動器,6 個總線可用(直到 IDE.5)
2 個網(wǎng)卡:1 個橋接到主機(需要更高的權(quán)限)和 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的互聯(lián)網(wǎng)訪問
QEMU 的默認網(wǎng)絡(luò)模式是“用戶模式網(wǎng)絡(luò)堆棧”。
在此模式下,充當出站TCP/UDP連接的代理。 它還為模擬系統(tǒng)提供DHCP和DNS服務(wù)。qemu
要提供對模擬OpenWrt系統(tǒng)的互聯(lián)網(wǎng)訪問,請使用(該示例使用armvirt系統(tǒng),請根據(jù)您的設(shè)置進行調(diào)整):
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系統(tǒng)中設(shè)置了兩個網(wǎng)卡:
eth0
,在OpenWrt中用作LAN(此處未連接到任何內(nèi)容)eth1
,在OpenWrt中用作WAN,并連接到qemu,它將代理所有TCP?/?UDP連接到互聯(lián)網(wǎng)
OpenWrt系統(tǒng)應(yīng)該同時打開IPv4和IPv6(通過DHCP?/ DHCPv6)。 范圍將是 10.0.2.0/24 和 fec0::/64。eth1
在OpenWrt中提供對LUCI的訪問
LUCI是OpenWrt使用的Web UI。 如果您想檢查LUCI的工作原理或使用LUCI應(yīng)用程序進行探索,則此設(shè)置適合您。 (該示例使用Armvirt系統(tǒng),請根據(jù)您的設(shè)置進行調(diào)整)
注意:此設(shè)置需要一些權(quán)限(在 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
網(wǎng)絡(luò)的工作原理:
eth0
,在OpenWrt中用作LAN,并連接到主機系統(tǒng)(靜態(tài)地址),提供對LUCI的訪問ledetap0
192.168.1.101/24
http://192.168.1.1
eth1
,在OpenWrt中用作WAN,并連接到qemu,它將代理所有TCP?/?UDP連接到互聯(lián)網(wǎng)
主機的轉(zhuǎn)發(fā)端口
如果在嵌入式系統(tǒng)上配置了不能使用的 NIC,則可以通過在選項中使用轉(zhuǎn)發(fā)(高)端口從主機訪問它們。-device
-nic
hostfwd=hostip:hostport-guestip:guestport
例如,要從客戶機系統(tǒng)上的主機訪問 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
如果網(wǎng)絡(luò)適配器是WAN接口,則必須在來賓中添加防火墻規(guī)則以允許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 網(wǎng)絡(luò)接口
(摘自菲利普·普林德維爾的郵件列表帖子)
在我的 Centos 7.4 KVM 主機上,我做到了:
要為每個網(wǎng)卡預(yù)配 10 個 VF,請執(zhí)行以下操作:
cat << EOF > /etc/modprobe.d/sr-iov.conf
# for SR-IOV support
options igb max_vfs=10
EOF
這將在下次重新啟動后生效。 或者通過卸載并重新加載IGB模塊。
為要支持虛擬化的每個 NIC 創(chuàng)建 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
創(chuàng)建 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 的架構(gòu)與目標映像相同時才有效(此處為 ARM cortex-a15)。
qemu-system-arm -nographic -M virt,accel=kvm -cpu host -m 64 -kernel openwrt-armvirt-zImage-initramfs
使用單獨的根引導(dǎo)
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 引導(dǎo)
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
轉(zhuǎn)載于
[OpenWrt Wiki]OpenWrt in QEMU