KVM & QEMU¶
KVM biến Linux kernel thành hypervisor, QEMU là chương trình userspace tạo VM và giả lập thiết bị. Hai thành phần này thường đi cùng nhau.
Phân vai¶
| Thành phần | Chạy ở | Vai trò |
|---|---|---|
KVM (kvm.ko, kèm kvm-intel/kvm-amd trên x86) |
Kernel | Dùng ảo hóa phần cứng (CPU, memory), chạy vCPU, xử lý các VM exit đơn giản |
| QEMU | Userspace | Cấp phát RAM cho guest, giả lập hoặc cung cấp thiết bị (virtio), xử lý các exit cần thiết bị (MMIO, PIO) |
| libvirt (tùy chọn) | Userspace | Lớp quản lý (XML, virsh, virt-manager) bên trên QEMU |
KVM không tự tạo được VM hoàn chỉnh vì thiếu thiết bị, nên cần một VMM (Virtual Machine Monitor) ở userspace. QEMU là VMM phổ biến nhất, ngoài ra có Firecracker, Cloud Hypervisor, crosvm (xem Sandbox & micro-VM).
Cách KVM hoạt động¶
Userspace nói chuyện với KVM qua các ioctl trên /dev/kvm:
KVM_CREATE_VM: tạo VM, nhận về một file descriptor.KVM_SET_USER_MEMORY_REGION: gán một vùng nhớ của tiến trình QEMU làm RAM của guest (GPA sang vùng nhớ đó).KVM_CREATE_VCPU: tạo vCPU, mỗi vCPU tương ứng một thread của QEMU.KVM_RUN: thread vào guest. Khi guest gây exit mà kernel không tự xử lý được (ví dụ truy cập MMIO của thiết bị giả lập),KVM_RUNtrả về userspace với lý do exit, QEMU xử lý rồi gọiKVM_RUNlại.
Vì vCPU là thread thường nên Linux scheduler, cgroups, taskset đều áp dụng được cho VM.
Ảo hóa và giả lập trong QEMU¶
QEMU có hai chế độ chạy mã guest:
- KVM accelerator (
-enable-kvmhoặc-accel kvm): kiến trúc guest phải trùng host, tốc độ gần native. - TCG (Tiny Code Generator): dịch lệnh động, cho phép guest khác kiến trúc (ARM trên x86), chậm hơn nhiều. Đây là giả lập, không phải ảo hóa.
QEMU còn có chế độ user-mode, chỉ chạy một chương trình khác kiến trúc, không phải cả hệ thống, xem QEMU cross-arch.
Kiểm tra máy có KVM¶
ls -l /dev/kvm # có node này là KVM đã sẵn sàng
grep -Ec '(vmx|svm)' /proc/cpuinfo # x86: >0 nghĩa là CPU hỗ trợ VT-x/AMD-V
lsmod | grep kvm
Quyền truy cập /dev/kvm thường cần thuộc nhóm kvm. Trong VM cloud hoặc Codespaces thường không có /dev/kvm nếu nhà cung cấp không bật nested virtualization.
Ví dụ¶
Tạo đĩa và chạy VM x86 với KVM, thiết bị virtio:
qemu-img create -f qcow2 disk.qcow2 20G
qemu-system-x86_64 -accel kvm -cpu host -m 2G -smp 2 \
-drive file=disk.qcow2,if=virtio \
-cdrom ubuntu.iso \
-netdev user,id=n0 -device virtio-net-pci,netdev=n0 \
-nographic
Chạy kernel ARM64 trên máy ảo virt (không cần board thật), rootfs nằm trên đĩa virtio:
qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 1G -smp 2 \
-kernel Image -append "console=ttyAMA0 root=/dev/vda rw" \
-drive file=rootfs.ext4,if=none,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=n0 -device virtio-net-device,netdev=n0 \
-nographic
Khi host cũng là ARM64 có KVM, thay -cpu cortex-a57 bằng -cpu host và thêm -accel kvm. Thoát QEMU ở chế độ -nographic: Ctrl + A rồi X.
Dùng trong phát triển embedded¶
- Thử kernel và driver trên máy
virt(ARM, ARM64, RISC-V) trước khi có board, debug bằng-s -S(gdbserver ở cổng 1234, dừng chờ debugger). - Phát triển driver virtio, kiểm thử device tree, boot flow với QEMU, kết hợp với Device Tree.
- Một số SoC (ví dụ nhiều dòng ARM64) chạy được KVM thật, dùng làm hypervisor cho Linux guest cạnh RTOS, nhưng nếu cần cô lập cứng và real-time hơn thì xem Partitioning hypervisor.