Booter une partition windows avec KVM
=====================================
Pour booter sur une partition windows depuis KVM, nous allons passer
par trois étapes :
#. Créer un disque à l'aide de ``mdadm`` enagrégeant des images au format ``raw``
et la partition, afin de recréer la table des partitions et la partition de boot.
#. Booter sur le disque créé et réinstaller la partition de boot à l'aide d'une
image d'installation Windows
#. Installer et paramétrer les drivers kvm pour Windows
Pour ce tutoriel, je me suis grandement inspiré de `ce tutoriel `_.
Installation des prérequis
--------------------------
On installe d'abord les paquets nécessaires à la virtualisation et ceux à la création des disques :
.. code-block:: bash
pacman -S qemu-full virt-manager dnsmasq mdadm dosfstools
Création du disque mdadm :
On se place dans le répertoire des images libvirt :
.. code-block:: bash
cd /var/lib/libvirt/images/
On créer ensuite les fichiers ``raw`` qui vont être agrégés à notre partition :
.. code-block:: bash
dd if=/dev/zero of=efi1 bs=1M count=200
dd if=/dev/zero of=efi2 bs=1M count=1
On identifie ensuite notre partition windows, par exemple ``/dev/nvme0n1p3``.
On vérifie que les modes nécessaires sont bien chargés, sinon on les démarre à la main :
.. code-block:: bash
lsmod | grep loop
lsmod | grep linear
# On charge les modules si nécessaire :
modprobe loop
modprobe linear
On regarde le device loop disponible et on monte ensuite les images en loopback :
.. code-block:: bash
losetup -f
losetup /dev/loop0 /var/lib/libvirt/images/efi1
losetup -f
losetup /dev/loop1 /var/lib/libvirt/images/efi2
Pour finir on créer le disque md0 qui agrège les deux loop et notre partition.
.. code-block:: bash
mdadm --build --verbose /dev/md0 --chunk=512 --level=linear --raid-devices=3 /dev/loop0 /dev/nvme0n1p3 /dev/loop1
Pour supprimer le disque, on utilise les commandes suivantes :
.. code-block:: bash
mdadm --stop /dev/md0
losetup -d /dev/loop0 /dev/loop1
Création de la table des partitions
-----------------------------------
Pour définir ou commence et ou finissent les partitions, il va falloir utiliser gparted avec les unités en secteur
et calculer la taille de nos fichiers raw en secteur.
On récupère la taille en bytes avec la commande ls -la, et on la divise par 512, la taille des secteurs que l'on a
choisie quand on à créé le disque ``mdadm`` avec l'option ``--chunk=512``.
.. image:: ./calculatesizeinsector.png
:width: 600px
On créer ensuite la table des partitions et la partiticon de boot :
.. code-block:: bash
parted /dev/md0
(parted) unit s # use sector size
(parted) mktable gpt
(parted) mkpart EFI fat32 2048 409599 # depends on size of efi1 file
(parted) mkpart Windows ntfs 409600 -2049 # depends on size of efi1 and efi2 files
(parted) set 1 boot on
(parted) set 1 esp on
(parted) set 2 msftdata on
(parted) quit
Pour être sur que notre table des partitions est bien alignée sur la partition windows, on peut la monter :
.. code-block:: bash
mount /dev/md0p2 /mnt
ls -lha /mnt
umount /mnt
Pour finir, on formate notre partition efi en fat 32 :
.. code-block:: bash
mkfs.fat -F 32 /dev/md0p1
Premier boot et installation de la partition de démarrage Windows
-----------------------------------------------------------------
On peut télécharger l'iso d'installation de Windows `ici `_
Lancement de la machine virtuelle et boot sur l'iso d'installation :
.. code-block:: bash
qemu-system-x86_64 \
-bios /usr/share/ovmf/x64/OVMF_CODE.fd \
-drive file=/dev/md0,media=disk,format=raw \
-cpu host -enable-kvm -m 4G \
-cdrom /root/Downloads/Win10_22H2_English_x64v1.iso
On peut ensuite lancer une invite de commande pour installer la partition de boot Windows :
.. code-block:: msdos
diskpart
DISKPART> list disk
DISKPART> select disk 0 # Select the disk
DISKPART> list volume # Find EFI volume (partition) number
DISKPART> select volume 2 # Select EFI volume
DISKPART> assign letter=B # Assign B: to EFI volume
DISKPART> exit
bcdboot C:\Windows /s B: /f ALL
exit
On peut éteindre l'ordinateur et redémarrer sans l'iso d'installation pour être sur que tout
fonctionne bien :
.. code-block:: bash
qemu-system-x86_64 \
-bios /usr/share/ovmf/x64/OVMF_CODE.fd \
-drive file=/dev/md0,media=disk,format=raw \
-cpu host -enable-kvm -m 4G
Création de la machine virtuelle dans virt-manager :
----------------------------------------------------
Création d'un script pour créer et supprimer ``/dev/md0``
---------------------------------------------------------
Pour faciliter la création et la suppression du volume mdadm, on peut utiliser un script tel que celui ci :
.. code-block:: bash
#!/bin/bash
_WINPART="/dev/nvme0n1p3"
cd $(dirname "$0") || exit 1
_EFIDIR=$(pwd)
_LOOP1=""
_LOOP2=""
_start() {
set -e
#Do nothing if md0 exist
[[ -e /dev/md0 ]] && printf "/dev/md0 already exists" && exit 1
# Enable modules if not loaded
lsmod | grep loop || modprobe loop
lsmod | grep linear || modprobe linear
_LOOP1=$(losetup -f)
losetup "$_LOOP1" "$_EFIDIR/efi1"
_LOOP2=$(losetup -f)
losetup "$_LOOP2" "$_EFIDIR/efi2"
mdadm --build --verbose /dev/md0 --chunk=512 --level=linear \
--raid-devices=3 "$_LOOP1" "$_WINPART" "$_LOOP2"
echo "$_LOOP1 $_LOOP2" > .loop-devices
}
_stop() {
mdadm --stop /dev/md0
xargs losetup -d < .loop-devices
}
_usage() {
cat << EOF
usage :
md0.sh start Create md0 device
md0.sh stop Destroy md0 device
EOF
}
[[ "$1" == "start" ]] && _start
[[ "$1" == "stop" ]] && _stop
[[ "$1" == "usage" ]] && _usage