系列文章目录
Linux内核学习
Linux 知识(1)
Linux 知识(2)
WSL Ubuntu
QEMU 虚拟机
Linux 调试视频
PCIe 与 USB 的补充知识
vscode 使用说明
树莓派 4B 指南
设备驱动畅想
Linux内核子系统
Linux 文件系统挂载
QEMU 通过网络实现共享文件
OrangePi 学习摘录 —— 制作桌面版镜像
Radxa 学习摘录
Rockchip RK3399 - 引导流程和准备工作
文章目录
- 系列文章目录
- 1、通过 virtfs 共享文件
- 1.1 在宿主机(Host)上设置共享目录
- 1.2 启动 QEMU 时配置
- -virtfs 选项
- -fsdev 和 -device 选项
- 1.3 虚拟机(Guest)中的配置
- 手动挂载
- 自动挂载(可选)
- 1.4 注意事项
- 2、网络配置
- 切换根文件
- NAT 模式
- 步骤 1:启动 QEMU 并配置 NAT 网络
- 步骤 2:在虚拟机中配置网络
- 步骤 3:验证网络连接
- 步骤 4:配置 DNS
- 步骤 5:配置 SSH 访问
- Tap 模式(网桥模式)
- 步骤 1:创建 TAP 接口
- 步骤 2:创建桥接接口
- 步骤 3:配置 QEMU 启动命令
- 注意事项
- 命令示例
1、通过 virtfs 共享文件
在 QEMU 中,virtfs
是一种高效且灵活的文件共享方式,它基于 9p 文件系统协议。以下是使用 virtfs
进行文件共享的详细步骤:
1.1 在宿主机(Host)上设置共享目录
创建一个目录,用于存放需要共享的文件:
mkdir -p /mnt/shared_folder
将需要共享的文件放入此目录中。
1.2 启动 QEMU 时配置
-virtfs 选项
-virtfs
选项用于指定共享目录的路径、安全模型以及挂载点等参数。以下是一个完整的命令示例:
qemu-system-x86_64 \-hda your_vm_image.img \-m 2048 \-enable-kvm \-virtfs local,path=/mnt/shared_folder,mount_tag=host_share,security_model=passthrough
-virtfs local
:表示使用本地目录作为共享文件夹。path=/mnt/shared_folder
:指定宿主机上的共享目录路径。mount_tag=host_share
:定义一个挂载标签(tag),用于在虚拟机中识别共享目录。security_model=passthrough
:指定安全模型,passthrough 表示直接把文件系统的权限和用户 ID 映射到虚拟机中。除了 passthrough,还可以选择 mapid(映射用户 ID)或 none(无安全模型)等其他安全模型,根据实际需求进行选择。
-fsdev 和 -device 选项
使用 -fsdev
和 -device virtio-9p
或 -device virtio-9p-mmio
来配置共享目录。以下是示例命令:
qemu-system-aarch64 \-machine virt \-cpu host \-m 2048 \-kernel /path/to/your/kernel \-append "root=/dev/vda2" \-drive file=/path/to/your/disk.img,format=qcow2 \-net none \-fsdev local,security_model=passthrough,id=fsdev0,path=/mnt/shared_folder \-device virtio-9p,fsdev=fsdev0,mount_tag=host_share
-fsdev local,security_model=passthrough,id=fsdev0,path=/mnt/shared_folder
:定义共享目录。-device virtio-9p,fsdev=fsdev0,mount_tag=host_share
:将共享目录挂载到虚拟机中。
注意:如果使用 -device virtio-9p-pci,可能会遇到 “No ‘PCI’ bus found” 错误。在这种情况下,可以使用 -device virtio-9p-mmio 替代。
1.3 虚拟机(Guest)中的配置
手动挂载
- 创建挂载点:
在虚拟机中创建一个目录,用于挂载共享文件夹。例如:
mkdir -p /mnt/shared
- 挂载共享文件夹:
使用以下命令挂载共享文件夹:
sudo mount -t 9p -o trans=virtio,version=9p2000.L host_share /mnt/shared
-t 9p
:指定文件系统类型为 9p。-o trans=virtio,version=9p2000.L
:指定传输协议为 virtio,文件系统版本为 9p2000.L。host_share
:共享目录的挂载标签(与 QEMU 启动命令中的 mount_tag 一致)。/mnt/shared
:虚拟机中的挂载点。
- 验证挂载:
挂载成功后,可以在 /mnt/shared 目录中访问宿主机上的共享文件。
自动挂载(可选)
为了在虚拟机重启后自动挂载共享文件夹,可以将挂载命令添加到 /etc/fstab 文件中。例如:
echo "host_share /mnt/shared 9p trans=virtio,version=9p2000.L,rw,share,nobootwait,posixacl,msize=104857600 0 0" >> /etc/fstab
然后运行以下命令使配置生效:
sudo mount -a
1.4 注意事项
- 内核支持:
确保虚拟机中的 Linux 内核支持 9p 文件系统。可以通过以下命令检查内核配置:
grep CONFIG_NET_9P /proc/config.gz
如果未启用,需要重新编译内核并启用以下选项:
- CONFIG_NET_9P
- CONFIG_NET_9P_VIRTIO
- CONFIG_9P_FS
- CONFIG_9P_FS_POSIX_ACL
- 权限问题:
如果在虚拟机中无法访问共享文件夹,可以检查宿主机上的文件权限。例如:
chmod -R 755 /mnt/shared_folder
- 网络配置:
如果虚拟机使用的是用户网络模式(-net user),可能需要调整防火墙设置,以允许 9p 协议的通信。
2、网络配置
切换根文件
# chroot target
chroot target /bin/sh
NAT 模式
在 QEMU 中运行 BusyBox 系统时,可以通过以下步骤配置 IP 地址并使其通过 NAT 访问外网:
步骤 1:启动 QEMU 并配置 NAT 网络
在启动 QEMU 时,使用 -netdev user 和 -device virtio-net 参数来配置 NAT 网络。以下是一个示例命令:
qemu-system-x86_64 \-m 2048 \-hda /path/to/your/disk.img \-netdev user,id=net0,ipv6=off,hostfwd=tcp::8022-:22 \-net nic,model=virtio
# -device virtio-net-device,netdev=net0
-netdev user,id=net0,ipv6=off,hostfwd=tcp::8022-:22
:配置 NAT 网络,hostfwd 参数将虚拟机的 22 端口(SSH)映射到宿主机的 8022 端口。-device virtio-net-device,netdev=net0
:将虚拟网卡连接到 NAT 网络。
步骤 2:在虚拟机中配置网络
虚拟机启动后,QEMU 会自动为虚拟机分配一个 NAT
网络。虚拟机可以通过以下命令检查网络配置:
ip addr show
如果虚拟机未分配 IP 地址,可以尝试以下方法:
- 方法 1:使用 DHCP 获取 IP 地址
BusyBox 默认安装了 udhcpc,可以通过以下命令获取 IP 地址:
udhcpc
udhcpc
会自动从 DHCP 服务器获取 IP 地址、子网掩码、默认网关和 DNS 服务器信息。获取到 IP 地址后,可以通过以下命令查看网络配置:
ip addr show
- 方法 2:手动配置静态 IP 地址
如果 DHCP 无法获取 IP 地址,可以手动配置静态 IP 地址。使用以下命令配置网络接口的 IP 地址和子网掩码:
# 启动网络接口
# ifconfig eth0 up
# ip link set eth0 upbusybox ifconfig eth0 10.0.2.15 netmask 255.255.255.0
然后添加默认网关:
busybox route add default gw 10.0.2.2
步骤 3:验证网络连接
在虚拟机中,使用以下命令测试网络连接:
ping 8.8.8.8
如果能够成功 ping 通,说明虚拟机已经可以访问外网。
步骤 4:配置 DNS
如果虚拟机可以 ping 通外网,但无法解析域名,可以编辑 /etc/resolv.conf 文件,添加 DNS 服务器地址:
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf# 查看 DNS 服务器
nmcli dev show | grep DNS
resolvectl status
cat /etc/resolv.conf
systemd-resolve --status
getent hosts www.baidu.com
dig www.baidu.com
nslookup g o o - g lx e . com
步骤 5:配置 SSH 访问
在虚拟机中安装并配置 SSH 服务,以便通过 SSH 访问虚拟机:
busybox ash
busybox opkg update
busybox opkg install dropbear
启动 dropbear 服务:
/etc/init.d/dropbear start
在宿主机上,可以通过以下命令连接到虚拟机的 SSH 服务:
ssh -p 8022 user@localhost
Tap 模式(网桥模式)
QEMU 的 Tap 模式(网桥模式)允许虚拟机通过一个虚拟的网络接口(TAP 接口)直接连接到宿主机的物理网络。这种方式使得虚拟机能够与宿主机以及同一网络中的其他设备直接通信。以下是详细的配置步骤:
步骤 1:创建 TAP 接口
- 创建 TAP 接口:
sudo ip tuntap add dev tap0 mode tap
这将创建一个名为 tap0 的 TAP 接口。
- 启用 TAP 接口:
sudo ip link set tap0 up
这将启用 tap0 接口。
步骤 2:创建桥接接口
- 创建桥接接口:
sudo ip link add name br0 type bridge
这将创建一个名为 br0 的桥接接口。
- 启用桥接接口:
sudo ip link set br0 up
这将启用 br0 桥接接口。
- 将物理网络接口添加到桥接接口:
假设宿主机的物理网络接口为 eth0:
sudo ip link set eth0 master br0
这将把 eth0 接口添加到 br0 桥接接口中。
- 将 TAP 接口添加到桥接接口:
sudo ip link set tap0 master br0
这将把 tap0 接口添加到 br0 桥接接口中。
步骤 3:配置 QEMU 启动命令
- 启动 QEMU 并配置 TAP 接口:
qemu-system-x86_64 \-m 2048 \-hda /path/to/your/disk.img \-netdev tap,id=net0,ifname=tap0,script=no,downscript=no \-device virtio-net-device,netdev=net0
-netdev tap,id=net0,ifname=tap0,script=no,downscript=no
:指定 TAP 接口的名称为 tap0,并禁用启动和关闭脚本。-device virtio-net-device,netdev=net0
:将虚拟网卡连接到 TAP 接口。
注意事项
- 权限问题:创建 TAP 接口和配置桥接接口需要管理员权限,因此需要使用 sudo。
- 网络配置:确保宿主机的网络配置支持桥接模式,特别是防火墙和网络策略。
- TAP 接口名称:TAP 接口的名称(如 tap0)可以根据需要自定义,但需要在 QEMU 启动命令中保持一致。
通过上述步骤,你可以在 QEMU 中配置 Tap 模式(网桥模式),使虚拟机能够直接访问宿主机的物理网络,并与同一网络中的其他设备通信。
命令示例
qemu-system-x86_64 \-kernel ${bzImagePath}/bzImage \-initrd initramfs.img \-m 1G -nographic \-virtfs local,path=/mnt/shared,mount_tag=host_share,security_model=none \-net user,id=net0,ipv6=off,hostfwd=tcp::8022-:22 \-net nic,model=virtio \-append "earlyprintk=serial,ttyS0 console=ttyS0 nokaslr"