使用 QEMU 創建 FreeBSD 16 Current VM
QEMU
基本的操作如下,來是 Gemini:

但我們在切換 FreeBSD tty 會用到 Ctrl + Alt 所以反而會切到 Linux host machine 的 TTY,可以在 QEMU Monitor 輸入 sendkey ctrl-alt-f2 手動輸入切換。
VirtIO
在沒有 VirtIO 的年代,虛擬機(Guest)如果要叫宿主機(Host)做事情,必須假裝自己是一台擁有舊硬體的實體機(比如模擬成一張 1990 年代的 Intel 網卡)。這種「演戲」的過程非常消耗 CPU 效能。
VirtIO 的運作原理:半虛擬化 (Para-virtualization)
- 前端 (Front-end):跑在你的 FreeBSD 虛擬機裡。它知道自己是虛擬的,所以它不傳送複雜的硬體訊號,而是直接把數據丟到記憶體的一塊「共享區域」。
- 後端 (Back-end):跑在你的 QEMU/KVM 裡。它直接從共享區域抓數據,交給實體硬體處理。
所以這邊可能可以用:
- VirtIO 模擬網卡 and Disk
- E1000 模擬 Intel 網卡 and SATA 硬碟
我們這邊使用第一種,FreeBSD 甚至內建 Kenrel 就有一些 virtio 驅動,清參考 Man page VIRTIO(4)。
FreeBSD 安裝
我們先用簡單的 amd64 ISO 檔案 FreeBSD-16.0-CURRENT-amd64-20260330-e6eba5076929-284768-disc1.iso。
kola:~/proj/freebsd_16_20260330$ ls
FreeBSD-16.0-CURRENT-amd64-20260330-e6eba5076929-284768-disc1.iso
kola:~/proj/freebsd_16_20260330$ qemu-img create -f qcow2 freebsd16.qcow2 50G
Formatting 'freebsd16.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=53687091200 lazy_refcounts=off refcount_bits=16
kola:~/proj/freebsd_16_20260330$ qemu-system-x86_64 \
-m 8G \
-cpu host \ # 這代表直接把 Linux 主機的 CPU 特性傳遞給虛擬機
-smp 6 \
-enable-kvm \ # 啟動 Linux 核心加速
-drive file=freebsd16.qcow2,if=virtio \ # 告訴 FreeBSD 這不是傳統的 IDE 或 SATA 硬碟,而是高效能的 VirtIO 區塊設備
-cdrom FreeBSD-16.0-CURRENT-amd64-20260330-e6eba5076929-284768-disc1.iso \ # 將 ISO 檔掛載到虛擬光碟機。安裝完成後,這行其實可以拿掉
-net nic,model=virtio -net user \ # 虛擬網卡使用 VirtIO 驅動。在 FreeBSD 裡會顯示為 vtnet0
-vga virtio \ # 模擬一張 VirtIO GPU。這是目前 QEMU 裡最強大的虛擬顯卡,支援 3D 加速
-display gtk,gl=on \ # gtk: 使用 Linux 系統常見的 GTK 視窗來顯示 QEM
-device virtio-tablet-pci \ # 這本來是為了實現「游標無縫進出」虛擬機的技術
-audiodev pa,id=snd0 \ # 讓 QEMU 的聲音輸出到 Linux 宿主機的 PulseAudio
-device intel-hda # 在虛擬機裡模擬一個 Intel 高傳真音效卡硬體
-device hda-duplex,audiodev=snd0 # 模擬的硬體(hda-duplex,支援輸入輸出)與剛才定義的後端(snd0)連接起來
qemu-system-x86_64 \
-m 8G \
-cpu host \
-smp 6 \
-enable-kvm \
-drive file=freebsd16.qcow2,if=virtio \
-net nic,model=virtio -net user \
-vga virtio \
-display gtk,gl=on \
-device virtio-tablet-pci \
-audiodev pa,id=snd0 \
-device intel-hda \
-device hda-duplex,audiodev=snd0
(qemu-system-x86_64:241929): Gtk-WARNING **: 19:23:20.366: Theme parsing error: gtk.css:2560:38: Junk at end of value for background之後就不需要 cdrom 參數了,但因為 -device virtio-tablet-pci,virtio-tablet 傳送的是「絕對座標」(例如:滑鼠現在在螢幕的 500, 300 處)。如果 FreeBSD 內核沒有正確載入 virtio_gpu 驅動來告訴系統「螢幕現在解析度是多少」,系統就會不知道這座標該往哪擺,最後只能讓下游標卡在螢幕正中央。
Mouse cursor not detected on FreeBSD virtual machine on Qemu
根據上面文章,在虛擬化環境中,普通的「滑鼠(Mouse)」通常是以相對座標運作,這在圖形介面(X11)中常導致虛擬機滑鼠與主機滑鼠不同步。為了解決這個問題,通常會改用「平板電腦(Tablet)」模式,它使用絕對座標,能讓滑鼠指哪打哪。
然而,FreeBSD 的舊版本核心對 QEMU 提供的 USB Tablet 或 VirtIO Tablet 支援並不完善,需要額外的驅動程式。
- 舊方法(針對 FreeBSD 12 或更早):需要手動安裝 utouch-kmod 驅動,並在 virt-manager 裡將輸入裝置設為 “EvTouch USB Graphics Tablet”
- 新方法(針對 FreeBSD 13、14 及更新版本):論壇最後一則回覆(#25)指出,現在不需要安裝額外套件了。FreeBSD 核心現在內建了 hms(4) 驅動來支援 HID 滑鼠/平板設備,但預設沒啟用
所以改成以下用 -usb -device usb-tablet,這讓 QEMU 模擬一個實體 USB 繪圖板。FreeBSD 內核裡的 hms 和 usbhid 驅動對這個裝置的支援非常穩,不管有沒有 3D 加速,它都能 100% 正常移動。
qemu-system-x86_64 \
-m 8G \
-cpu host \
-smp 6 \
-enable-kvm \
-drive file=freebsd16.qcow2,if=virtio \
-net nic,model=virtio -net user \
-vga virtio \
-display gtk,gl=on \
-usb -device usb-tablet \
-audiodev pa,id=snd0 \
-device intel-hda \
-device hda-duplex,audiodev=snd0網路
User-mode Networking (SLIRP),這模式是 QEMU 的預設值。你可以把它想像成 「QEMU 內建的一個小型 Proxy 伺服器」。
QEMU 會攔截虛擬機發出的所有 TCP/UDP 封包,然後在 Linux 宿主機(Host)上以普通使用者的身分重新發送這些請求。
因為在 Linux 裡,發送 ICMP(Ping)封包需要 Raw Socket 權限,而普通使用者啟動的 QEMU 行程沒有這個權限,所以 SLIRP 乾脆不模擬 ICMP。
TAP 模式(最推薦,最像實體機) 這是在 Linux 上實現虛擬化最標準的做法。它會在你的 Linux 裡建立一個虛擬網卡(例如 tap0),然後透過 Bridge(網橋) 把這張虛擬網卡跟你的實體網卡(例如 eth0)連在一起。 效果:FreeBSD 會從你的路由器(Router)直接拿到一個跟 Linux 主機同區網的 IP(例如 192.168.1.50)。 能力:可以被 Ping,可以從 Linux 直接 SSH 進去,甚至可以在區網內玩檔案共享。
Port Forwarding(懶人折衷法) 如果你不想搞複雜的網橋,但又想連進 FreeBSD,可以在原本的 SLIRP 模式加一個「傳送門」。 指令範例:-netdev user,id=n1,hostfwd=tcp::2222-:22 效果:你在 Linux 連線 localhost:2222,封包會被轉發到虛擬機的 22 埠。
Passthrough(硬體直通) 如果你有兩張實體網卡,可以直接把其中一張「送給」虛擬機。 效果:效能最高,但那張網卡在 Linux 宿主機上會消失,專供 FreeBSD 使用。
VMware 預設通常是 NAT 模式 或 Bridged (橋接) 模式。雖然聽起來跟 QEMU 的 User Mode (SLIRP) 很像,但底層實現完全不同:
VMware 的 NAT 模式:它在你的 Linux 宿主機中安裝了內核級別的驅動程式(這就是為什麼你安裝 VMware 時需要輸入密碼,還要編譯一堆 vmnet 模組)。這些驅動讓 VMware 擁有了「特權」,可以直接在 Linux 核心層級處理網路封包,模擬出一台功能完整的虛擬路由器。
QEMU 的 User Mode (SLIRP):它是一個純粹的使用者層級 (User-space) 程式。它不觸碰內核,只靠標準的系統呼叫來傳輸資料。因為它沒有特權,所以無法偽造 ICMP (Ping) 封包。
桌面環境
有驅動(VirtIO GPU):可以支援解析度自動調整、雙螢幕,以及最重要的 OpenGL 加速,這對 KDE 6 的特效至關重要。 包含在 drm-kmod 裡面
看要不要安裝 “noto-2.0”?
sudo pkg install -y xorg
sudo pw groupmod video -m [user]
sudo pkg install kde
sudo pkg install dbus # 其實不用跑已經安裝了
sudo sysrc dbus_enable="YES"
sudo sysrc net.local.stream.recvspace=65536
sudo sysrc net.local.stream.sendspace=65536
sudo pkg drm-kmod # 包含 QEMU 的 virtio_gpu.ko 驅動
# sysrc kld_list+="virtio_gpu"
### ----------------------------------------- ###
sudo pkg install plasma6-sddm-kcm # KDE 的控制模組 (KCM),讓你可以在 KDE 的「系統設定」介面裡直接設定 SDDM 登入畫面
sudo pkg install sddm # Simple Desktop Display Manager。雖然是獨立計畫,但它是 KDE 官方推薦的登入程式,支援 X11 與 Wayland
sudo sysrc hald_enable="YES"
sudo sysrc sddm_enable="YES"
sudo sysrc snd_driver_load="YES"Debug
進度 ISO loader prompt。


set currdev=disk0p2:
ls /boot/kernel/kernel
load /boot/kernel/kernel
boot