Windows 11 в голом QEMU/KVM на MX Linux: один скрипт, без virt-manager
Есть у меня Debian-виртуалка, которую я годами запускаю одной строкой через alias в .bashrc. Без libvirt-XML, без virt-manager: qemu-system-x86_64 с пачкой флагов, SPICE-экран и мост в локальную сеть. Понадобилась рядом Windows 11, и захотелось сделать её так же, одним скриптом, который можно прочитать глазами и понять целиком.
Оказалось, что «так же» не получится. Windows 11 требует UEFI с Secure Boot и TPM 2.0, не знает про virtio и по-своему считает время. В статье разберу, что пришлось поменять, зачем нужен каждый флаг и на какие грабли я наступил во время установки.
Всё, что ниже, лежит в репозитории: github.com/ramanzes/qemu-win11-mx.
Исходная точка
Вот как запускается Debian-гость:
☯
Terminal:
⌕
≡
✕
alias qemudebian='sudo qemu-system-x86_64 \
-enable-kvm \
-m 8192 -smp 2 \
-machine pc-q35-7.2 \
-cpu host \
-drive file=/var/lib/libvirt/images/debian13.qcow2,if=virtio,format=qcow2 \
-boot order=c \
-netdev bridge,br=virbr0,id=net0 \
-device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \
-vga qxl \
-device virtio-tablet \
-spice port=5930,disable-ticketing=on \
-device intel-hda -device hda-duplex \
-monitor stdio'Почему не virt-manager? Он хороший, но конфигурация живёт в XML где-то в /etc/libvirt, и когда что-то идёт не так, приходится разбираться, во что libvirt превратил твои галочки. Тут же вся машина видна на одном экране. Её можно скопировать, закоммитить в git и поправить одной строкой.
Хост: MX Linux (он на базе Debian 12), процессор с аппаратной виртуализацией.
Чем Windows 11 отличается от Linux-гостя
Если взять alias выше и просто подсунуть ISO с Windows 11, установщик скажет «Этот компьютер не соответствует требованиям». Отличий четыре.
- UEFI и Secure Boot. По умолчанию QEMU грузится через SeaBIOS, то есть legacy BIOS. Windows 11 нужен UEFI, а для Secure Boot ещё и прошивка с ключами Microsoft. Это даёт пакет
ovmf. - TPM 2.0. Физический TPM хоста отдавать не нужно, есть программный эмулятор
swtpm. QEMU подключается к нему через сокет. - virtio. Linux знает virtio из коробки, Windows нет. Диск и сеть virtio установщик просто не увидит, пока не подсунешь драйверы с отдельного ISO
virtio-win.iso. - Мелочи.
virtio-tabletбез драйвера в Windows не работает, аusb-tabletработает. Windows по умолчанию считает, что аппаратные часы идут в локальном времени, а не в UTC.
Подготовка хоста
Пакеты
☯
Terminal:
⌕
≡
✕
sudo apt install qemu-system-x86 qemu-utils ovmf swtpm swtpm-tools \
libvirt-daemon-system virt-viewerСначала проверяем, что процессор умеет в виртуализацию:
☯
Terminal:
⌕
≡
✕
egrep -c '(vmx|svm)' /proc/cpuinfo
Если вывод 0, идём в BIOS и включаем Intel VT-x или AMD-V (SVM).
libvirt-daemon-system здесь нужен не ради virt-manager, а ради сети: libvirt поднимает мост virbr0 с DHCP и NAT. Сам QEMU libvirt'ом не управляется.
Сеть: мост virbr0
Есть особенность MX Linux: по умолчанию он грузится с sysvinit, поэтому systemctl не поможет. Используем service:
☯
Terminal:
⌕
≡
✕
sudo service libvirtd start sudo virsh net-start default sudo virsh net-autostart default
QEMU подключается к мосту через qemu-bridge-helper. Хелпер откажется работать с мостом, которого нет в белом списке:
☯
Terminal:
⌕
≡
✕
sudo mkdir -p /etc/qemu echo "allow virbr0" | sudo tee /etc/qemu/bridge.conf
Без этого файла запуск упадёт с ошибкой access denied by acl file.
Диск, UEFI-переменные, TPM
☯
Terminal:
⌕
≡
✕
cd /var/lib/libvirt/images sudo qemu-img create -f qcow2 win11.qcow2 80G sudo cp /usr/share/OVMF/OVMF_VARS_4M.ms.fd win11_VARS.fd sudo mkdir -p win11-tpm
Здесь важно понимать, что OVMF состоит из двух файлов:
OVMF_CODE_4M.secboot.fd— сама прошивка. Она общая и подключается только на чтение.OVMF_VARS_4M.ms.fd— шаблон NVRAM, то есть переменных UEFI: порядок загрузки, ключи Secure Boot. Суффикс.msзначит, что в него уже записаны ключи Microsoft. Каждой ВМ нужна своя копия, потому что прошивка в неё пишет.
Если вместо копии подключить системный шаблон напрямую, вы либо получите ошибку доступа, либо (под sudo) молча испортите шаблон для всех будущих машин.
Если у вас других имён файлов, посмотрите ls /usr/share/OVMF/. Набор зависит от версии пакета.
ISO-образы
☯
Terminal:
⌕
≡
✕
sudo wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso
Сам Win11.iso скачиваем с официальной страницы microsoft.com/software-download и кладём в ту же папку.
Скрипт запуска
☯
Terminal:
⌕
≡
✕
#!/bin/bash IMG=/var/lib/libvirt/images # TPM-эмулятор: запускается перед каждым стартом ВМ sudo swtpm socket --tpm2 --daemon \ --tpmstate dir=$IMG/win11-tpm \ --ctrl type=unixio,path=$IMG/win11-tpm/sock sudo qemu-system-x86_64 \ -enable-kvm -m 8192 -smp 4 \ -machine q35,smm=on \ -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \ -global driver=cfi.pflash01,property=secure,value=on \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.secboot.fd \ -drive if=pflash,format=raw,file=$IMG/win11_VARS.fd \ -chardev socket,id=chrtpm,path=$IMG/win11-tpm/sock \ -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 \ -drive file=$IMG/win11.qcow2,if=virtio,format=qcow2 \ -drive file=$IMG/Win11.iso,media=cdrom \ -drive file=$IMG/virtio-win.iso,media=cdrom \ -boot menu=on \ -rtc base=localtime \ -netdev bridge,br=virbr0,id=net0 \ -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:57 \ -vga qxl \ -device qemu-xhci -device usb-tablet \ -spice port=5931,disable-ticketing=on \ -device intel-hda -device hda-duplex \ -monitor stdio
Разберу по блокам, что тут нового по сравнению с Debian.
TPM
☯
Terminal:
⌕
≡
✕
swtpm socket --tpm2 --daemon \ --tpmstate dir=$IMG/win11-tpm \ --ctrl type=unixio,path=$IMG/win11-tpm/sock
swtpm — это отдельный процесс, который эмулирует TPM 2.0 и хранит его состояние в win11-tpm/. Папку нельзя удалять: если включите в Windows BitLocker, его ключи окажутся там.
Со стороны QEMU три параметра: -chardev открывает сокет, -tpmdev emulator говорит «TPM живёт по ту сторону сокета», -device tpm-tis создаёт само устройство, которое увидит гость.
UEFI и Secure Boot
☯
Terminal:
⌕
≡
✕
-machine q35,smm=on -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,...,readonly=on,file=.../OVMF_CODE_4M.secboot.fd -drive if=pflash,...,file=$IMG/win11_VARS.fd
Сборка OVMF с Secure Boot требует режима SMM (System Management Mode). Это smm=on. Флаг secure=on для pflash защищает переменные от записи из обычного режима, иначе гость мог бы переписать ключи Secure Boot в обход прошивки. Без этих двух флагов secboot-прошивка просто не запустится: будет чёрный экран.
Флаг -boot order=c из Debian-версии тут не работает. Порядок загрузки при UEFI хранит сама прошивка в VARS. Вместо него -boot menu=on: в начале загрузки можно нажать Esc и выбрать устройство вручную.
Hyper-V enlightenments
☯
Terminal:
⌕
≡
✕
-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
Windows умеет определять, что работает под гипервизором, и использует паравиртуальные интерфейсы Hyper-V. KVM умеет их эмулировать:
hv_relaxedотключает watchdog, который в виртуалке при нагрузке на хост может выдавать BSODCLOCK_WATCHDOG_TIMEOUT;hv_spinlocksдаёт гостю подсказку, когда отдать процессор вместо бесконечной крутилки на спинлоке;hv_vapic— паравиртуальный контроллер прерываний;hv_time— паравиртуальные часы, главный пункт для отзывчивости.
Без них Windows работает, но заметно медленнее, особенно когда простаивает: виртуалка ест процессор хоста.
Диски
☯
Terminal:
⌕
≡
✕
-drive file=$IMG/win11.qcow2,if=virtio,format=qcow2 -drive file=$IMG/Win11.iso,media=cdrom -drive file=$IMG/virtio-win.iso,media=cdrom
Два CD-привода: установщик и драйверы. На машине q35 CD-приводы садятся на SATA (AHCI), который Windows знает. А вот системный диск virtio, и как раз с этим связана первая грабля (о ней ниже).
Остальное
-rtc base=localtime: Windows считает, что аппаратные часы идут в местном времени. Если отдать ей UTC (как Linux-гостю), часы в Windows будут сдвинуты на ваш часовой пояс.-device qemu-xhci -device usb-tablet: USB 3.0 контроллер и планшет. Планшет даёт абсолютные координаты курсора, и мышь не «залипает» в окне.usb-tabletWindows понимает без драйверов, в отличие отvirtio-tablet.- MAC
...:57и SPICE-порт5931отличаются от Debian-гостя (...:56и5930), чтобы обе машины могли работать одновременно.
Подключаемся к экрану:
☯
Terminal:
⌕
≡
✕
remote-viewer spice://localhost:5931
Установка и грабли
«Press any key to boot from CD»
Первая надпись появится на пару секунд, и пока вы переключаетесь в окно viewer'а, она может пропасть. Тогда UEFI не найдёт загрузочного диска и вывалится в UEFI Shell. Ничего страшного: введите reset и будьте быстрее, или нажмите Esc на старте и выберите CD в Boot Manager.
Установщик не видит диск
Доходим до выбора раздела, а там пусто. Первая мысль: что-то не так с образом. Проверяю на хосте:
☯
Terminal:
⌕
≡
✕
$ sudo ls -la /var/lib/libvirt/images/win11.qcow2 -rw-r--r-- 1 root root 393216 Oct 15 12:28 win11.qcow2
384 килобайта вместо 80 гигабайт выглядят тревожно, но это нормально. qcow2 — разреженный формат, файл растёт по мере записи. Настоящий размер показывает qemu-img info:
☯
Terminal:
⌕
≡
✕
sudo qemu-img info /var/lib/libvirt/images/win11.qcow2 # virtual size: 80 GiB
Проблема не в диске, а в драйвере: диск подключён как virtio, а установщик Windows про virtio не знает. Лечится так:
- Нажимаем «Загрузить драйвер», затем «Обзор».
- Открываем CD virtio-win и папку
viostor\w11\amd64. - Выбираем Red Hat VirtIO SCSI controller и жмём «Далее».
- Появляется «Незанятое пространство на диске 0: 80 ГБ».
Если драйвер не появляется в списке, снимите галочку «Скрыть драйверы, несовместимые с оборудованием» и проверьте, что выбрали w11\amd64, а не w10 или ARM64.
Совет, который я бы хотел знать заранее: на этом же экране загрузите и драйвер сети, NetKVM\w11\amd64. Тогда установщик сразу увидит сеть, и следующей грабли не будет.
Можно было бы обойти проблему, подключив диск как SATA, но тогда вы потеряете в скорости. Одна загрузка драйвера стоит того.
Нет сети при первом запуске (OOBE)
Я про NetKVM вспомнил уже после того, как установка пошла. Windows 11 Home и Pro на этапе первичной настройки хотят интернет и учётку Microsoft, а сетевой карты не видно.
Начинать заново не нужно, вариантов три.
Кнопка «Установить драйвер». Когда сетевой карты нет, на экране «Подключитесь к сети» обычно есть такая ссылка. Указываем ей NetKVM\w11\amd64 на CD virtio.
Командная строка. Если кнопки нет: Shift+F10, находим букву CD с драйверами (dir D:, dir E:, нужен тот, где лежат папки NetKVM и viostor) и ставим драйвер вручную:
☯
Terminal:
⌕
≡
✕
pnputil /add-driver E:\NetKVM\w11\amd64\*.inf /install
Через несколько секунд сеть появится. Если экран не обновится сам, нажмите «Назад».
Локальная учётка без сети. Shift+F10, затем:
☯
Terminal:
⌕
≡
✕
start ms-cxh:localonly
Откроется окно создания локального пользователя. На старых сборках Windows 11 то же самое делал OOBE\BYPASSNRO, но в свежих его убрали. Драйвер сети тогда ставим уже из системы (см. ниже).
После установки
Открываем CD virtio-win и запускаем virtio-win-guest-tools.exe. Он ставит сразу всё: сеть, видеодрайвер QXL (без него разрешение не поднимется выше базового), balloon, а ещё SPICE agent. Последний даёт общий буфер обмена с хостом и автоматическое разрешение при изменении размера окна viewer'а.
После этого обе строки с ISO из скрипта можно удалить или закомментировать.
Что можно улучшить
Скрипт намеренно простой. Если хочется выжать больше, вот направления, которые я оставил на потом:
- Явная топология CPU.
-smp 4,sockets=1,cores=4,threads=1. Windows для клиентских редакций ограничивает число процессорных сокетов, поэтому лучше давать ядра, а не сокеты. Свежий QEMU и так раскладывает-smp 4по ядрам, но явное лучше неявного. - Кеш и TRIM.
cache=none,aio=native,discard=unmapв строке диска: меньше двойного кеширования, и qcow2 будет сжиматься, когда Windows освобождает место.discardдля virtio-blk работает в свежих версиях QEMU и драйвера. - Больше enlightenments.
hv_vpindex,hv_synic,hv_stimer,hv_reset,hv_frequencies. Или одним флагомhv-passthrough(тогда, правда, теряется переносимость на другое железо). - Не от root. Сейчас всё запускается через
sudo, так проще с доступом к/var/lib/libvirt/imagesи мосту. Аккуратнее положить образы в домашнюю папку, добавить себя в группуkvmи датьqemu-bridge-helperбит setuid (в Debian так и задумано).
Итог
Отличия от Linux-гостя сводятся к четырём вещам: OVMF с Secure Boot, swtpm, драйверы virtio с отдельного ISO и пара мелких флагов. Основные проблемы при установке вызывает virtio: установщик не видит ни диск, ни сеть, пока ему не подсунуть драйверы. Если загрузить viostor и NetKVM на экране выбора диска, установка проходит без сюрпризов.
Скрипт и инструкция на русском и английском: github.com/ramanzes/qemu-win11-mx. Pull request'ы с улучшениями приветствуются.
-
Создано 17.10.2026 18:58:00
-
Roman Sakhno

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.