
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://allan.eti.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://allan.eti.br/" rel="alternate" type="text/html" /><updated>2024-11-19T03:11:18+00:00</updated><id>https://allan.eti.br/feed.xml</id><title type="html">Allan M. de Azevedo</title><subtitle>1 + 1 = 10</subtitle><author><name>Allan</name></author><entry><title type="html">GPU passthrough via OVMF e VFIO - Passando uma placa de vídeo para máquina virtual</title><link href="https://allan.eti.br/2022/09/22/gpu-passthrough-via-ovmf-e-vfio.html" rel="alternate" type="text/html" title="GPU passthrough via OVMF e VFIO - Passando uma placa de vídeo para máquina virtual" /><published>2022-09-22T00:00:00+00:00</published><updated>2022-09-22T00:00:00+00:00</updated><id>https://allan.eti.br/2022/09/22/gpu-passthrough-via-ovmf-e-vfio</id><content type="html" xml:base="https://allan.eti.br/2022/09/22/gpu-passthrough-via-ovmf-e-vfio.html"><![CDATA[<p>O caso descrito neste post considera o <em>HP EliteDesk 805 G6 Small Form Factor PC</em> com as seguintes especificações:</p>
<ul>
  <li>Processador: AMD Ryzen 7 PRO 4750G</li>
  <li>GPU integrado: AMD Radeon Vega 7 Graphics</li>
  <li>GPU offboard: AMD Radeon R7 430 2 GB GDDR5 64-bit 2 DP Graphics Card</li>
</ul>

<h2 id="pré-requisitos">Pré-requisitos</h2>
<ul>
  <li>Ter pelo menos duas GPUs;
    <ul>
      <li>Sugestão: onboard para o host e offboard para a máquina virtual;</li>
    </ul>
  </li>
  <li>IOMMU ativo;</li>
  <li>Máquina virtual no libvirt com UEFI (OVMF);</li>
  <li>Opcionalmente, ter um monitor plugado na saída da GPU que será utilizada para a máquina virtual;</li>
</ul>

<p>O script a seguir verifica se o IOMMU está ativo e com os grupos válidos:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nb">shopt</span> <span class="nt">-s</span> nullglob
<span class="k">for </span>g <span class="k">in</span> <span class="si">$(</span>find /sys/kernel/iommu_groups/<span class="k">*</span> <span class="nt">-maxdepth</span> 0 <span class="nt">-type</span> d | <span class="nb">sort</span> <span class="nt">-V</span><span class="si">)</span><span class="p">;</span> <span class="k">do
    </span><span class="nb">echo</span> <span class="s2">"IOMMU Group </span><span class="k">${</span><span class="nv">g</span><span class="p">##*/</span><span class="k">}</span><span class="s2">:"</span>
    <span class="k">for </span>d <span class="k">in</span> <span class="nv">$g</span>/devices/<span class="k">*</span><span class="p">;</span> <span class="k">do
        </span><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\t</span><span class="si">$(</span>lspci <span class="nt">-nns</span> <span class="k">${</span><span class="nv">d</span><span class="p">##*/</span><span class="k">}</span><span class="si">)</span><span class="s2">"</span>
    <span class="k">done</span><span class="p">;</span>
<span class="k">done</span><span class="p">;</span>
</code></pre></div></div>

<h2 id="isolando-a-gpu">Isolando a GPU</h2>

<p>Identifique a GPU que será isolada por meio do comando <code class="language-plaintext highlighter-rouge">lspci</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lspci -D | grep VGA
0000:01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (rev 87)
0000:07:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Renoir (rev d8)
</code></pre></div></div>

<p>No meu caso, <code class="language-plaintext highlighter-rouge">0000:01:00.0</code> é o ID da placa offboard.</p>

<h3 id="modprobed">modprobe.d</h3>

<p>Utilize o <code class="language-plaintext highlighter-rouge">modprobe</code> para inicializar o módulo <code class="language-plaintext highlighter-rouge">vfio-pci</code> durante o boot. Todos os dispositivos do grupo IOMMU precisam ser informados para o <code class="language-plaintext highlighter-rouge">vfio-pci</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lspci -n -s 01:00
01:00.0 0300: 1002:6611 (rev 87)
01:00.1 0403: 1002:aab0
</code></pre></div></div>

<p>Crie o arquivo <code class="language-plaintext highlighter-rouge">/etc/modprobe.d/vfio.conf</code> adicionando os identificadores dos dispositivos:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>options vfio-pci ids=1002:6611,1002:aab0
</code></pre></div></div>

<p>Para descobrir o driver atualmente em uso pela GPU que será isolada, use o comando:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lspci -v -s 01:00
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (rev 87) (prog-if 00 [VGA controller])
        Subsystem: Hewlett-Packard Company Device 3375
        Flags: bus master, fast devsel, latency 0, IRQ 97, IOMMU group 0
        Memory at c0000000 (64-bit, prefetchable) [size=256M]
        Memory at fc800000 (64-bit, non-prefetchable) [size=256K]
        I/O ports at 3000 [size=256]
        Expansion ROM at fc860000 [disabled] [size=128K]
        Capabilities: &lt;access denied&gt;
        Kernel driver in use: vfio-pci
        Kernel modules: radeon, amdgpu

01:00.1 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series]
        Subsystem: Hewlett-Packard Company Device aab0
        Flags: bus master, fast devsel, latency 0, IRQ 94, IOMMU group 0
        Memory at fc840000 (64-bit, non-prefetchable) [size=16K]
        Capabilities: &lt;access denied&gt;
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel
</code></pre></div></div>

<p>Crie o arquivo <code class="language-plaintext highlighter-rouge">/etc/modprobe.d/blacklist.conf</code> e adicione a diretiva <code class="language-plaintext highlighter-rouge">blacklist</code> juntamente com o driver retornado, para que o mesmo não seja carregado pelo host (afinal, o dispositivo será passado inteiramente para a máquina virtual):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>blacklist radeon
</code></pre></div></div>

<p>Gere uma nova imagem do <code class="language-plaintext highlighter-rouge">initramfs</code> após as modificações nas configurações do <code class="language-plaintext highlighter-rouge">modprobe</code>.</p>

<h2 id="configuração-da-máquina-virtual">Configuração da máquina virtual</h2>

<p>Crie uma nova máquina virtual no <code class="language-plaintext highlighter-rouge">virt-manager</code> com as seguintes especificações:</p>
<ul>
  <li>Sistema Operacional: Microsoft Windows 10</li>
  <li>Firmware: UEFI (OVMF)</li>
  <li>Modelo de CPU: <code class="language-plaintext highlighter-rouge">host-passthrough</code></li>
  <li>Modelo de vídeo: QXL</li>
</ul>

<p>Edite manualmente a configuração XML da máquina virtual (<code class="language-plaintext highlighter-rouge">virsh edit</code>) e adicione a entrada <code class="language-plaintext highlighter-rouge">vendor_id</code> da feature <code class="language-plaintext highlighter-rouge">hyperv</code> com um valor qualquer:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="nt">&lt;hyperv&gt;</span>
      <span class="nt">&lt;relaxed</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vapic</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;spinlocks</span> <span class="na">state=</span><span class="s">"on"</span> <span class="na">retries=</span><span class="s">"8191"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vpindex</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;synic</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;stimer</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;reset</span> <span class="na">state=</span><span class="s">"on"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vendor_id</span> <span class="na">state=</span><span class="s">"on"</span> <span class="na">value=</span><span class="s">"00110011"</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hyperv&gt;</span>
</code></pre></div></div>

<p>Depois que instalar o Windows 10, adicione todos os dispositivos PCI do grupo IOMMU na máquina virtual.</p>

<p><img src="/assets/vm-pci-devs.png" alt="vm-pci-devs.png" /></p>

<h3 id="virsh-dumpxml-win10-uefi-clone">virsh dumpxml win10-uefi-clone</h3>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;domain</span> <span class="na">type=</span><span class="s">'kvm'</span><span class="nt">&gt;</span>
  <span class="nt">&lt;name&gt;</span>win10-uefi-clone<span class="nt">&lt;/name&gt;</span>
  <span class="nt">&lt;uuid&gt;</span>00000000-1111-2222-3333-444444444444<span class="nt">&lt;/uuid&gt;</span>
  <span class="nt">&lt;metadata&gt;</span>
    <span class="nt">&lt;libosinfo:libosinfo</span> <span class="na">xmlns:libosinfo=</span><span class="s">"http://libosinfo.org/xmlns/libvirt/domain/1.0"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;libosinfo:os</span> <span class="na">id=</span><span class="s">"http://microsoft.com/win/10"</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/libosinfo:libosinfo&gt;</span>
  <span class="nt">&lt;/metadata&gt;</span>
  <span class="nt">&lt;memory</span> <span class="na">unit=</span><span class="s">'KiB'</span><span class="nt">&gt;</span>4194304<span class="nt">&lt;/memory&gt;</span>
  <span class="nt">&lt;currentMemory</span> <span class="na">unit=</span><span class="s">'KiB'</span><span class="nt">&gt;</span>4194304<span class="nt">&lt;/currentMemory&gt;</span>
  <span class="nt">&lt;vcpu</span> <span class="na">placement=</span><span class="s">'static'</span><span class="nt">&gt;</span>4<span class="nt">&lt;/vcpu&gt;</span>
  <span class="nt">&lt;os&gt;</span>
    <span class="nt">&lt;type</span> <span class="na">arch=</span><span class="s">'x86_64'</span> <span class="na">machine=</span><span class="s">'pc-q35-6.1'</span><span class="nt">&gt;</span>hvm<span class="nt">&lt;/type&gt;</span>
    <span class="nt">&lt;loader</span> <span class="na">readonly=</span><span class="s">'yes'</span> <span class="na">type=</span><span class="s">'pflash'</span><span class="nt">&gt;</span>/usr/share/edk2/ovmf/OVMF_CODE.fd<span class="nt">&lt;/loader&gt;</span>
    <span class="nt">&lt;nvram&gt;</span>/var/lib/libvirt/qemu/nvram/win10-uefi-clone_VARS.fd<span class="nt">&lt;/nvram&gt;</span>
    <span class="nt">&lt;bootmenu</span> <span class="na">enable=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/os&gt;</span>
  <span class="nt">&lt;features&gt;</span>
    <span class="nt">&lt;acpi/&gt;</span>
    <span class="nt">&lt;apic/&gt;</span>
    <span class="nt">&lt;hyperv&gt;</span>
      <span class="nt">&lt;relaxed</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vapic</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;spinlocks</span> <span class="na">state=</span><span class="s">'on'</span> <span class="na">retries=</span><span class="s">'8191'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vpindex</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;synic</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;stimer</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;reset</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vendor_id</span> <span class="na">state=</span><span class="s">'on'</span> <span class="na">value=</span><span class="s">'00110011'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hyperv&gt;</span>
    <span class="nt">&lt;vmport</span> <span class="na">state=</span><span class="s">'off'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/features&gt;</span>
  <span class="nt">&lt;cpu</span> <span class="na">mode=</span><span class="s">'host-passthrough'</span> <span class="na">check=</span><span class="s">'partial'</span> <span class="na">migratable=</span><span class="s">'on'</span><span class="nt">&gt;</span>
    <span class="nt">&lt;topology</span> <span class="na">sockets=</span><span class="s">'1'</span> <span class="na">dies=</span><span class="s">'1'</span> <span class="na">cores=</span><span class="s">'4'</span> <span class="na">threads=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/cpu&gt;</span>
  <span class="nt">&lt;clock</span> <span class="na">offset=</span><span class="s">'localtime'</span><span class="nt">&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'rtc'</span> <span class="na">tickpolicy=</span><span class="s">'catchup'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'pit'</span> <span class="na">tickpolicy=</span><span class="s">'delay'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'hpet'</span> <span class="na">present=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'hypervclock'</span> <span class="na">present=</span><span class="s">'yes'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/clock&gt;</span>
  <span class="nt">&lt;on_poweroff&gt;</span>destroy<span class="nt">&lt;/on_poweroff&gt;</span>
  <span class="nt">&lt;on_reboot&gt;</span>restart<span class="nt">&lt;/on_reboot&gt;</span>
  <span class="nt">&lt;on_crash&gt;</span>destroy<span class="nt">&lt;/on_crash&gt;</span>
  <span class="nt">&lt;pm&gt;</span>
    <span class="nt">&lt;suspend-to-mem</span> <span class="na">enabled=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;suspend-to-disk</span> <span class="na">enabled=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/pm&gt;</span>
  <span class="nt">&lt;devices&gt;</span>
    <span class="nt">&lt;emulator&gt;</span>/usr/bin/qemu-system-x86_64<span class="nt">&lt;/emulator&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'file'</span> <span class="na">device=</span><span class="s">'disk'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'qcow2'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">file=</span><span class="s">'/var/lib/libvirt/images/hdd/win10-uefi-clone.qcow2'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'vda'</span> <span class="na">bus=</span><span class="s">'virtio'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;boot</span> <span class="na">order=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x04'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'file'</span> <span class="na">device=</span><span class="s">'cdrom'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'raw'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">file=</span><span class="s">'/var/lib/libvirt/images/iso/pt_windows_10_enterprise_ltsc_2019_x64_dvd_d43dcbad.iso'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'sdb'</span> <span class="na">bus=</span><span class="s">'sata'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;readonly/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'drive'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">target=</span><span class="s">'0'</span> <span class="na">unit=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'file'</span> <span class="na">device=</span><span class="s">'cdrom'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'raw'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">file=</span><span class="s">'/var/lib/libvirt/images/iso/virtio-win-0.1.204.iso'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'sdc'</span> <span class="na">bus=</span><span class="s">'sata'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;readonly/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'drive'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">target=</span><span class="s">'0'</span> <span class="na">unit=</span><span class="s">'2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">index=</span><span class="s">'0'</span> <span class="na">model=</span><span class="s">'qemu-xhci'</span> <span class="na">ports=</span><span class="s">'15'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x02'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'sata'</span> <span class="na">index=</span><span class="s">'0'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x1f'</span> <span class="na">function=</span><span class="s">'0x2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'0'</span> <span class="na">model=</span><span class="s">'pcie-root'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'1'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'1'</span> <span class="na">port=</span><span class="s">'0x10'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x0'</span> <span class="na">multifunction=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'2'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'2'</span> <span class="na">port=</span><span class="s">'0x11'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'3'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'3'</span> <span class="na">port=</span><span class="s">'0x12'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'4'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'4'</span> <span class="na">port=</span><span class="s">'0x13'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x3'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'5'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'5'</span> <span class="na">port=</span><span class="s">'0x14'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x4'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'6'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'6'</span> <span class="na">port=</span><span class="s">'0x15'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x5'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'7'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'7'</span> <span class="na">port=</span><span class="s">'0x16'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x6'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'8'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'8'</span> <span class="na">port=</span><span class="s">'0x17'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x7'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'virtio-serial'</span> <span class="na">index=</span><span class="s">'0'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x03'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;interface</span> <span class="na">type=</span><span class="s">'network'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;mac</span> <span class="na">address=</span><span class="s">'52:54:00:11:33:55'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">network=</span><span class="s">'default'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">type=</span><span class="s">'virtio'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;link</span> <span class="na">state=</span><span class="s">'up'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x01'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/interface&gt;</span>
    <span class="nt">&lt;serial</span> <span class="na">type=</span><span class="s">'pty'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'isa-serial'</span> <span class="na">port=</span><span class="s">'0'</span><span class="nt">&gt;</span>
        <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'isa-serial'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/target&gt;</span>
    <span class="nt">&lt;/serial&gt;</span>
    <span class="nt">&lt;console</span> <span class="na">type=</span><span class="s">'pty'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'serial'</span> <span class="na">port=</span><span class="s">'0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/console&gt;</span>
    <span class="nt">&lt;channel</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'virtio'</span> <span class="na">name=</span><span class="s">'com.redhat.spice.0'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'virtio-serial'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/channel&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'tablet'</span> <span class="na">bus=</span><span class="s">'usb'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/input&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'mouse'</span> <span class="na">bus=</span><span class="s">'ps2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'keyboard'</span> <span class="na">bus=</span><span class="s">'ps2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;graphics</span> <span class="na">type=</span><span class="s">'spice'</span> <span class="na">autoport=</span><span class="s">'yes'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;listen</span> <span class="na">type=</span><span class="s">'address'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;image</span> <span class="na">compression=</span><span class="s">'off'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/graphics&gt;</span>
    <span class="nt">&lt;sound</span> <span class="na">model=</span><span class="s">'ich9'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x1b'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/sound&gt;</span>
    <span class="nt">&lt;audio</span> <span class="na">id=</span><span class="s">'1'</span> <span class="na">type=</span><span class="s">'spice'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;video&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">type=</span><span class="s">'qxl'</span> <span class="na">ram=</span><span class="s">'65536'</span> <span class="na">vram=</span><span class="s">'65536'</span> <span class="na">vgamem=</span><span class="s">'16384'</span> <span class="na">heads=</span><span class="s">'1'</span> <span class="na">primary=</span><span class="s">'yes'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x01'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/video&gt;</span>
    <span class="nt">&lt;hostdev</span> <span class="na">mode=</span><span class="s">'subsystem'</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">managed=</span><span class="s">'yes'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;source&gt;</span>
        <span class="nt">&lt;address</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x01'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x1'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/source&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x06'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hostdev&gt;</span>
    <span class="nt">&lt;hostdev</span> <span class="na">mode=</span><span class="s">'subsystem'</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">managed=</span><span class="s">'yes'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;source&gt;</span>
        <span class="nt">&lt;address</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x01'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/source&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x07'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hostdev&gt;</span>
    <span class="nt">&lt;hostdev</span> <span class="na">mode=</span><span class="s">'subsystem'</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">managed=</span><span class="s">'yes'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;source&gt;</span>
        <span class="nt">&lt;address</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x01'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/source&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x08'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hostdev&gt;</span>
    <span class="nt">&lt;redirdev</span> <span class="na">bus=</span><span class="s">'usb'</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/redirdev&gt;</span>
    <span class="nt">&lt;redirdev</span> <span class="na">bus=</span><span class="s">'usb'</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'3'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/redirdev&gt;</span>
    <span class="nt">&lt;memballoon</span> <span class="na">model=</span><span class="s">'virtio'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x05'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/memballoon&gt;</span>
  <span class="nt">&lt;/devices&gt;</span>
<span class="nt">&lt;/domain&gt;</span>
</code></pre></div></div>

<p>Ligue a máquina virtual, instale os drivers de vídeo da GPU redirecionada ou aguarde o Windows instalá-los automaticamente e desligue a máquina novamente.</p>

<p>No <code class="language-plaintext highlighter-rouge">virt-manager</code>, remova o dispositivo gráfico e altere o modelo de vídeo para <code class="language-plaintext highlighter-rouge">none</code>. Depois, substitua o teclado e mouse por dois dispositivos <code class="language-plaintext highlighter-rouge">evdev</code> relativos aos que estão em uso no host.</p>

<div class="language-patch highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gd">--- win10-uefi-clone_qxl.xml	2022-06-27 09:38:44.316924953 -0300
</span><span class="gi">+++ win10-uefi-clone_radeon.xml	2022-06-27 09:38:17.964727495 -0300
</span><span class="p">@@ -138,22 +138,20 @@</span>
       &lt;target type='virtio' name='com.redhat.spice.0'/&gt;
       &lt;address type='virtio-serial' controller='0' bus='0' port='1'/&gt;
     &lt;/channel&gt;
<span class="gd">-    &lt;input type='tablet' bus='usb'&gt;
-      &lt;address type='usb' bus='0' port='1'/&gt;
</span><span class="gi">+    &lt;input type='evdev'&gt;
+      &lt;source dev='/dev/input/by-id/usb-PixArt_HP_320M_USB_Optical_Mouse-event-mouse'/&gt;
+    &lt;/input&gt;
+    &lt;input type='evdev'&gt;
+      &lt;source dev='/dev/input/by-id/usb-Primax_HP_Wired_Desktop_320K_Keyboard-event-kbd' grab='all' repeat='on'/&gt;
</span>     &lt;/input&gt;
     &lt;input type='mouse' bus='ps2'/&gt;
     &lt;input type='keyboard' bus='ps2'/&gt;
<span class="gd">-    &lt;graphics type='spice' autoport='yes'&gt;
-      &lt;listen type='address'/&gt;
-      &lt;image compression='off'/&gt;
-    &lt;/graphics&gt;
</span>     &lt;sound model='ich9'&gt;
       &lt;address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/&gt;
     &lt;/sound&gt;
     &lt;audio id='1' type='spice'/&gt;
     &lt;video&gt;
<span class="gd">-      &lt;model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/&gt;
-      &lt;address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/&gt;
</span><span class="gi">+      &lt;model type='none'/&gt;
</span>     &lt;/video&gt;
     &lt;hostdev mode='subsystem' type='pci' managed='yes'&gt;
       &lt;source&gt;
</code></pre></div></div>

<p>Ao ligar a máquina virtual, duas coisas acontecerão: (1) o mouse e o teclado ficarão congelados no host. Isso se deve aos dispositivos <code class="language-plaintext highlighter-rouge">evdev</code> adicionados à vm. Para alternar o controle destes dispositivos entre host e guest, pressione [<code class="language-plaintext highlighter-rouge">left Ctrl + right Ctrl</code>]; (2) A tela da máquina virtual ficará disponível na saída de vídeo que foi redirecionada (no caso deste post, na saída da placa offboard).</p>

<h2 id="referências">Referências</h2>

<p><a href="https://www.linux-kvm.org/page/OVMF">OVMF - KVM</a></p>

<p><a href="https://docs.kernel.org/driver-api/vfio.html">VFIO - “Virtual Function I/O” — The Linux Kernel  documentation</a></p>

<p><a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF">PCI passthrough via OVMF - ArchWiki</a></p>

<p><a href="https://pve.proxmox.com/wiki/Pci_passthrough">Pci passthrough - Proxmox VE</a></p>]]></content><author><name>Allan</name></author><category term="libvirt" /><category term="kvm" /><category term="gpu-passthrough" /><category term="ovmf" /><category term="vfio" /><summary type="html"><![CDATA[O caso descrito neste post considera o HP EliteDesk 805 G6 Small Form Factor PC com as seguintes especificações: Processador: AMD Ryzen 7 PRO 4750G GPU integrado: AMD Radeon Vega 7 Graphics GPU offboard: AMD Radeon R7 430 2 GB GDDR5 64-bit 2 DP Graphics Card]]></summary></entry><entry><title type="html">Dual-boot diferente - Usando máquina virtual no Linux para dar boot em partição física com Windows 10</title><link href="https://allan.eti.br/2022/05/07/dual-boot-diferente.html" rel="alternate" type="text/html" title="Dual-boot diferente - Usando máquina virtual no Linux para dar boot em partição física com Windows 10" /><published>2022-05-07T00:00:00+00:00</published><updated>2022-05-07T00:00:00+00:00</updated><id>https://allan.eti.br/2022/05/07/dual-boot-diferente</id><content type="html" xml:base="https://allan.eti.br/2022/05/07/dual-boot-diferente.html"><![CDATA[<p>Multi-booting é a ação de instalar múltiplos sistemas operacionais num mesmo computador e poder escolher qual deles você quer iniciar (ou “dar o boot”).</p>

<p>Uma das configurações mais populares de multi-boot é a inicialação dupla (“dual-boot”) com Windows e Linux.</p>

<p>Para ter um sistema com dual-boot, normalmente se faz o seguinte:</p>

<ul>
  <li>Instalação do Windows, particionando apenas uma parte do disco;</li>
  <li>Instalação do Linux no espaço livre deixado;</li>
  <li>Instalação de um bootloader (GRUB, por exemplo) para que seja possível escolher qual sistema operacional você deseja iniciar;</li>
</ul>

<p>Lembrei que há mais de 10 anos eu tinha uma instalação dual-boot (Windows XP e Ubuntu) e, na época, acabei seguindo uma dica<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> para que fosse possível dar boot na instalação física do Windows por meio de uma máquina virtual do VMware no Linux.</p>

<p>Só que as coisas (no meu computador principal) não são mais como eram antigamente:</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Windows</th>
      <th>Linux</th>
      <th>Hypervisor</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Antigamente</td>
      <td>XP</td>
      <td>Ubuntu</td>
      <td>VMware Workstation</td>
    </tr>
    <tr>
      <td>“Presentemente”</td>
      <td>10</td>
      <td>Fedora</td>
      <td>KVM</td>
    </tr>
  </tbody>
</table>

<p>Mas a vontade de dar boot na partição física do Windows em uma máquina virtual no Linux continuou :)</p>

<p>Pesquisando sobre o assunto, confirmei que é possível dar boot numa instalação física do Windows usando uma máquina virtual do QEMU.<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup> <sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">3</a></sup></p>

<p>Em vez de passar o disco inteiro para a máquina virtual tendo o risco de corromper as outras partições e seus dados, é recomendado criar dispositivos loopback para a partição EFI e tabela GPT. Depois, basta criar uma RAID-0 virtual com estes dispositivos e a partição física do Windows.</p>

<h2 id="preparação-do-disco-virtual">Preparação do disco virtual</h2>

<p>Usando o esquema GPT, vamos criar dois arquivos para conter a partição EFI e um espaço vazio:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">efi0</code> de 100MB</li>
  <li><code class="language-plaintext highlighter-rouge">efi1</code> de 1MB</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dd if=/dev/zero of=efi0 bs=1M count=100
dd if=/dev/zero of=efi1 bs=1M count=1
</code></pre></div></div>

<p>Com os dois arquivos criados, precisamos transformá-los em dispositivos de bloco (loopback devices) usando o <code class="language-plaintext highlighter-rouge">losetup</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo losetup loop0 efi0
sudo losetup loop1 efi1
</code></pre></div></div>

<p>Se a criação dos dispositivos deu certo, eles serão listados no comando:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>losetup -a
</code></pre></div></div>

<p>Depois, é preciso juntar os dispositivos loopack e a partição do Windows numa RAID-0 virtual na seguinte sequência:</p>
<ul>
  <li>/dev/loop0</li>
  <li>/dev/[partição do Windows - no meu caso, sda4]</li>
  <li>/dev/loop1</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo mdadm --build --verbose /dev/md0 --chunk=512 --level=linear --raid-devices=3 /dev/loop0 /dev/sda4 /dev/loop1
</code></pre></div></div>

<p>Temos então um disco virtual “zerado” contendo a partição física do Windows. Precisamos então criar a tabela de partições deste disco:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% sudo parted /dev/md0
GNU Parted 3.4
Using /dev/md0
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) mktable gpt
(parted) mkpart primary fat32 2048 204799
(parted) mkpart primary ntfs 204800 -2049
(parted) set 1 boot on
(parted) set 1 esp on
(parted) set 2 msftdata on
(parted) name 1 EFI
(parted) name 2 Windows
(parted) quit
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">unit s</code> define a unidade padrão a ser usada para <em>setores</em></li>
  <li>cada setor tem 512 bytes</li>
  <li>204800 setores = 102400 KiB = 100 MiB</li>
</ul>

<p>A tabela de partições do RAID-0 ficará assim:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">/dev/md0p1</code> - partição EFI</li>
  <li><code class="language-plaintext highlighter-rouge">/dev/md0p2</code> - partição física do Windows</li>
</ul>

<p>O próximo passo é formatar a partição EFI como um sistema de arquivos FAT32:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkfs.msdos -F 32 -n EFI /dev/md0p1
</code></pre></div></div>

<p>Crie uma máquina virtual usando o <em>virt-manager</em> com os padrões para o Windows 10 e adicione o disco virtual <code class="language-plaintext highlighter-rouge">/dev/md0</code> como disco SATA.</p>

<p><img src="/assets/dual-boot-1.png" alt="Máquina virtual - disco /dev/md0" /></p>

<p>Agora temos que recuperar os arquivos de boot do Windows usando o <strong>BCDBoot</strong><sup id="fnref:4" role="doc-noteref"><a href="#fn:4" class="footnote" rel="footnote">4</a></sup>.</p>

<p>Para poder usar esta ferramenta é preciso dar boot na mídia de instalação do Windows. Quando aparecer a janela de instalação, pressione <strong>Shift + F10</strong> para abrir uma janela do prompt de comando.</p>

<p><img src="/assets/dual-boot-2.png" alt="Janela de instalação do Windows 10" />
<img src="/assets/dual-boot-3.png" alt="Shift + F10 para abrir a janela do prompt de comando" /></p>

<p>Antes, devemos atribuir uma letra para a partição EFI usando o <strong>diskpart</strong><sup id="fnref:5" role="doc-noteref"><a href="#fn:5" class="footnote" rel="footnote">5</a></sup>.</p>

<p>Selecione o disco e a partição corretas para que <code class="language-plaintext highlighter-rouge">S:</code> aponte para a partição EFI.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>X:\Sources&gt;diskpart
DISKPART&gt; list disk
DISKPART&gt; select disk 0
DISKPART&gt; list volume
DISKPART&gt; select volume 2
DISKPART&gt; assign letter=S
DISKPART&gt; exit
</code></pre></div></div>

<p>E no meu caso a unidade <code class="language-plaintext highlighter-rouge">C:</code> estava com o BitLocker ativado. Tive que desbloqueá-la usando o <strong>manage-bde</strong><sup id="fnref:6" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">6</a></sup> antes de recuperar os arquivos de boot do Windows pelo <strong>BCDBoot</strong>.</p>

<p><img src="/assets/dual-boot-4.png" alt="Desbloqueando o Bitlocker usando o manage-bde" /></p>

<p>Por fim, criamos os arquivos de configuração de boot do Windows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bcdboot C:\Windows /s S: /f ALL
</code></pre></div></div>

<p>Pronto! Agora basta reiniciar a máquina virtual que o Windows da partição física será iniciado com sucesso.</p>

<p><img src="/assets/dual-boot-5.png" alt="Máquina virtual iniciando o Windows 10 a partir da partição física" /></p>

<h2 id="observações-finais">Observações finais</h2>

<p>Toda vez que reiniciar o Linux será preciso recriar os dispositivos de loopback (loop0 e loop1) e o disco virtual (md0).</p>

<p>A máquina virtual, por padrão, não terá uma GPU dedicada. Não cheguei a testar <em>GPU passthrough</em> ou <em>iGVT-g</em> nela. O driver de vídeo QXL foi suficiente para minha necessidade.</p>

<p>É recomendável instalar o <strong>SPICE guest tools</strong><sup id="fnref:7" role="doc-noteref"><a href="#fn:7" class="footnote" rel="footnote">7</a></sup> e o <strong>Virtio-win guest tools</strong><sup id="fnref:8" role="doc-noteref"><a href="#fn:8" class="footnote" rel="footnote">8</a></sup> no Windows 10.</p>

<p>Se a unidade <code class="language-plaintext highlighter-rouge">C:</code> estiver criptografada, é bom adicionar uma unidade USB extra na VM e criar uma chave externa do BitLocker. A minha instalação do Windows estava com o BitLocker ativado com o <em>Trusted Module Platform</em> (TPM). Como eu não quis mexer com <em>TPM passthrough</em>, achei mais simples criar a chave externa e deixá-la num disco QCOW2 como sendo uma unidade USB.</p>

<p>BCD significa “Boot Configuration Data”.</p>

<hr />

<h2 id="virsh-dumpxml-win10-dual-boot">virsh dumpxml win10-dual-boot</h2>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;domain</span> <span class="na">type=</span><span class="s">'kvm'</span><span class="nt">&gt;</span>
  <span class="nt">&lt;name&gt;</span>win10-dual-boot<span class="nt">&lt;/name&gt;</span>
  <span class="nt">&lt;uuid&gt;</span>00000000-1111-2222-3333-444444444444<span class="nt">&lt;/uuid&gt;</span>
  <span class="nt">&lt;metadata&gt;</span>
    <span class="nt">&lt;libosinfo:libosinfo</span> <span class="na">xmlns:libosinfo=</span><span class="s">"http://libosinfo.org/xmlns/libvirt/domain/1.0"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;libosinfo:os</span> <span class="na">id=</span><span class="s">"http://microsoft.com/win/10"</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/libosinfo:libosinfo&gt;</span>
  <span class="nt">&lt;/metadata&gt;</span>
  <span class="nt">&lt;memory</span> <span class="na">unit=</span><span class="s">'KiB'</span><span class="nt">&gt;</span>4194304<span class="nt">&lt;/memory&gt;</span>
  <span class="nt">&lt;currentMemory</span> <span class="na">unit=</span><span class="s">'KiB'</span><span class="nt">&gt;</span>4194304<span class="nt">&lt;/currentMemory&gt;</span>
  <span class="nt">&lt;vcpu</span> <span class="na">placement=</span><span class="s">'static'</span><span class="nt">&gt;</span>2<span class="nt">&lt;/vcpu&gt;</span>
  <span class="nt">&lt;os&gt;</span>
    <span class="nt">&lt;type</span> <span class="na">arch=</span><span class="s">'x86_64'</span> <span class="na">machine=</span><span class="s">'pc-q35-6.1'</span><span class="nt">&gt;</span>hvm<span class="nt">&lt;/type&gt;</span>
    <span class="nt">&lt;loader</span> <span class="na">readonly=</span><span class="s">'yes'</span> <span class="na">type=</span><span class="s">'pflash'</span><span class="nt">&gt;</span>/usr/share/edk2/ovmf/OVMF_CODE.fd<span class="nt">&lt;/loader&gt;</span>
    <span class="nt">&lt;nvram&gt;</span>/var/lib/libvirt/qemu/nvram/win10-dual-boot_VARS.fd<span class="nt">&lt;/nvram&gt;</span>
    <span class="nt">&lt;bootmenu</span> <span class="na">enable=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/os&gt;</span>
  <span class="nt">&lt;features&gt;</span>
    <span class="nt">&lt;acpi/&gt;</span>
    <span class="nt">&lt;apic/&gt;</span>
    <span class="nt">&lt;hyperv&gt;</span>
      <span class="nt">&lt;relaxed</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vapic</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;spinlocks</span> <span class="na">state=</span><span class="s">'on'</span> <span class="na">retries=</span><span class="s">'8191'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;vpindex</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;synic</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;stimer</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;reset</span> <span class="na">state=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/hyperv&gt;</span>
    <span class="nt">&lt;vmport</span> <span class="na">state=</span><span class="s">'off'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/features&gt;</span>
  <span class="nt">&lt;cpu</span> <span class="na">mode=</span><span class="s">'host-passthrough'</span> <span class="na">check=</span><span class="s">'none'</span> <span class="na">migratable=</span><span class="s">'on'</span><span class="nt">&gt;</span>
    <span class="nt">&lt;topology</span> <span class="na">sockets=</span><span class="s">'1'</span> <span class="na">dies=</span><span class="s">'1'</span> <span class="na">cores=</span><span class="s">'2'</span> <span class="na">threads=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/cpu&gt;</span>
  <span class="nt">&lt;clock</span> <span class="na">offset=</span><span class="s">'localtime'</span><span class="nt">&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'rtc'</span> <span class="na">tickpolicy=</span><span class="s">'catchup'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'pit'</span> <span class="na">tickpolicy=</span><span class="s">'delay'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'hpet'</span> <span class="na">present=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;timer</span> <span class="na">name=</span><span class="s">'hypervclock'</span> <span class="na">present=</span><span class="s">'yes'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/clock&gt;</span>
  <span class="nt">&lt;on_poweroff&gt;</span>destroy<span class="nt">&lt;/on_poweroff&gt;</span>
  <span class="nt">&lt;on_reboot&gt;</span>restart<span class="nt">&lt;/on_reboot&gt;</span>
  <span class="nt">&lt;on_crash&gt;</span>destroy<span class="nt">&lt;/on_crash&gt;</span>
  <span class="nt">&lt;pm&gt;</span>
    <span class="nt">&lt;suspend-to-mem</span> <span class="na">enabled=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;suspend-to-disk</span> <span class="na">enabled=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/pm&gt;</span>
  <span class="nt">&lt;devices&gt;</span>
    <span class="nt">&lt;emulator&gt;</span>/usr/bin/qemu-system-x86_64<span class="nt">&lt;/emulator&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'file'</span> <span class="na">device=</span><span class="s">'cdrom'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'raw'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">file=</span><span class="s">'/var/lib/libvirt/images/iso/pt_windows_10_enterprise_ltsc_2019_x64_dvd_d43dcbad.iso'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'sda'</span> <span class="na">bus=</span><span class="s">'sata'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;readonly/&gt;</span>
      <span class="nt">&lt;boot</span> <span class="na">order=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'drive'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">target=</span><span class="s">'0'</span> <span class="na">unit=</span><span class="s">'0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'block'</span> <span class="na">device=</span><span class="s">'disk'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'raw'</span> <span class="na">cache=</span><span class="s">'none'</span> <span class="na">io=</span><span class="s">'native'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">dev=</span><span class="s">'/dev/md0'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'sdb'</span> <span class="na">bus=</span><span class="s">'sata'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;boot</span> <span class="na">order=</span><span class="s">'2'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'drive'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">target=</span><span class="s">'0'</span> <span class="na">unit=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;disk</span> <span class="na">type=</span><span class="s">'file'</span> <span class="na">device=</span><span class="s">'disk'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;driver</span> <span class="na">name=</span><span class="s">'qemu'</span> <span class="na">type=</span><span class="s">'qcow2'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">file=</span><span class="s">'/var/lib/libvirt/images/win10-usb.qcow2'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">dev=</span><span class="s">'sdc'</span> <span class="na">bus=</span><span class="s">'usb'</span> <span class="na">removable=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;readonly/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'4'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/disk&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">index=</span><span class="s">'0'</span> <span class="na">model=</span><span class="s">'qemu-xhci'</span> <span class="na">ports=</span><span class="s">'15'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x02'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'sata'</span> <span class="na">index=</span><span class="s">'0'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x1f'</span> <span class="na">function=</span><span class="s">'0x2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'0'</span> <span class="na">model=</span><span class="s">'pcie-root'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'1'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'1'</span> <span class="na">port=</span><span class="s">'0x10'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x0'</span> <span class="na">multifunction=</span><span class="s">'on'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'2'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'2'</span> <span class="na">port=</span><span class="s">'0x11'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'3'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'3'</span> <span class="na">port=</span><span class="s">'0x12'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'4'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'4'</span> <span class="na">port=</span><span class="s">'0x13'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x3'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">index=</span><span class="s">'5'</span> <span class="na">model=</span><span class="s">'pcie-root-port'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'pcie-root-port'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">chassis=</span><span class="s">'5'</span> <span class="na">port=</span><span class="s">'0x14'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x02'</span> <span class="na">function=</span><span class="s">'0x4'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;controller</span> <span class="na">type=</span><span class="s">'virtio-serial'</span> <span class="na">index=</span><span class="s">'0'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x03'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/controller&gt;</span>
    <span class="nt">&lt;interface</span> <span class="na">type=</span><span class="s">'network'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;mac</span> <span class="na">address=</span><span class="s">'52:54:00:11:22:33'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;source</span> <span class="na">network=</span><span class="s">'default'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">type=</span><span class="s">'virtio'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;link</span> <span class="na">state=</span><span class="s">'up'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x01'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/interface&gt;</span>
    <span class="nt">&lt;serial</span> <span class="na">type=</span><span class="s">'pty'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'isa-serial'</span> <span class="na">port=</span><span class="s">'0'</span><span class="nt">&gt;</span>
        <span class="nt">&lt;model</span> <span class="na">name=</span><span class="s">'isa-serial'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/target&gt;</span>
    <span class="nt">&lt;/serial&gt;</span>
    <span class="nt">&lt;console</span> <span class="na">type=</span><span class="s">'pty'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'serial'</span> <span class="na">port=</span><span class="s">'0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/console&gt;</span>
    <span class="nt">&lt;channel</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;target</span> <span class="na">type=</span><span class="s">'virtio'</span> <span class="na">name=</span><span class="s">'com.redhat.spice.0'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'virtio-serial'</span> <span class="na">controller=</span><span class="s">'0'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/channel&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'tablet'</span> <span class="na">bus=</span><span class="s">'usb'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'1'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/input&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'mouse'</span> <span class="na">bus=</span><span class="s">'ps2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">'keyboard'</span> <span class="na">bus=</span><span class="s">'ps2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;graphics</span> <span class="na">type=</span><span class="s">'spice'</span> <span class="na">autoport=</span><span class="s">'yes'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;listen</span> <span class="na">type=</span><span class="s">'address'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;image</span> <span class="na">compression=</span><span class="s">'off'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;gl</span> <span class="na">enable=</span><span class="s">'no'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/graphics&gt;</span>
    <span class="nt">&lt;sound</span> <span class="na">model=</span><span class="s">'ich9'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x1b'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/sound&gt;</span>
    <span class="nt">&lt;audio</span> <span class="na">id=</span><span class="s">'1'</span> <span class="na">type=</span><span class="s">'spice'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;video&gt;</span>
      <span class="nt">&lt;model</span> <span class="na">type=</span><span class="s">'qxl'</span> <span class="na">ram=</span><span class="s">'65536'</span> <span class="na">vram=</span><span class="s">'65536'</span> <span class="na">vgamem=</span><span class="s">'16384'</span> <span class="na">heads=</span><span class="s">'1'</span> <span class="na">primary=</span><span class="s">'yes'</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x00'</span> <span class="na">slot=</span><span class="s">'0x01'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/video&gt;</span>
    <span class="nt">&lt;redirdev</span> <span class="na">bus=</span><span class="s">'usb'</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'2'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/redirdev&gt;</span>
    <span class="nt">&lt;redirdev</span> <span class="na">bus=</span><span class="s">'usb'</span> <span class="na">type=</span><span class="s">'spicevmc'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'usb'</span> <span class="na">bus=</span><span class="s">'0'</span> <span class="na">port=</span><span class="s">'3'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/redirdev&gt;</span>
    <span class="nt">&lt;memballoon</span> <span class="na">model=</span><span class="s">'virtio'</span><span class="nt">&gt;</span>
      <span class="nt">&lt;address</span> <span class="na">type=</span><span class="s">'pci'</span> <span class="na">domain=</span><span class="s">'0x0000'</span> <span class="na">bus=</span><span class="s">'0x04'</span> <span class="na">slot=</span><span class="s">'0x00'</span> <span class="na">function=</span><span class="s">'0x0'</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;/memballoon&gt;</span>
  <span class="nt">&lt;/devices&gt;</span>
<span class="nt">&lt;/domain&gt;</span>
</code></pre></div></div>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p><a href="https://mazimi.wordpress.com/2007/06/24/virtualization-of-an-existing-physical-partition-of-windows-within-linux/">Never reboot linux again?  Run your existing Windows install in Linux! | Mohammad Azimi</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p><a href="https://wiki.archlinux.org/title/QEMU#Using_any_real_partition_as_the_single_primary_partition_of_a_hard_disk_image">QEMU - ArchWiki - Using any real partition as the single primary partition of a hard disk image</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3" role="doc-endnote">
      <p><a href="https://lejenome.tik.tn/post/boot-physical-windows-inside-qemu-guest-machine">Boot physical Windows inside Qemu guest machine | Moez Bouhlel [lejenome] Website</a> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:4" role="doc-endnote">
      <p><a href="https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/bcdboot-command-line-options-techref-di?view=windows-10">BCDBoot Command-Line Options | Microsoft Docs</a> <a href="#fnref:4" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:5" role="doc-endnote">
      <p><a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/diskpart">diskpart | Microsoft Docs</a> <a href="#fnref:5" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:6" role="doc-endnote">
      <p><a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/manage-bde">manage-bde | Microsoft Docs</a> <a href="#fnref:6" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:7" role="doc-endnote">
      <p><a href="https://www.spice-space.org/download.html#windows-binaries">SPICE - Download - Guest - Windows binaries</a> <a href="#fnref:7" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:8" role="doc-endnote">
      <p><a href="https://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers">WindowsGuestDrivers/Download Drivers - KVM</a> <a href="#fnref:8" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Allan</name></author><category term="libvirt" /><category term="kvm" /><category term="qemu" /><category term="windows" /><category term="linux" /><category term="dual-boot" /><category term="bitlocker" /><summary type="html"><![CDATA[Multi-booting é a ação de instalar múltiplos sistemas operacionais num mesmo computador e poder escolher qual deles você quer iniciar (ou “dar o boot”).]]></summary></entry><entry><title type="html">Consumo anormal de CPU em máquinas virtuais QEMU com usb-tablet (USB 2)</title><link href="https://allan.eti.br/2022/01/11/consumo-anormal-de-cpu-em-maquinas-virtuais-qemu-com-usb-tablet-usb-2.html" rel="alternate" type="text/html" title="Consumo anormal de CPU em máquinas virtuais QEMU com usb-tablet (USB 2)" /><published>2022-01-11T00:00:00+00:00</published><updated>2022-01-11T00:00:00+00:00</updated><id>https://allan.eti.br/2022/01/11/consumo-anormal-de-cpu-em-maquinas-virtuais-qemu-com-usb---tablet-usb-2</id><content type="html" xml:base="https://allan.eti.br/2022/01/11/consumo-anormal-de-cpu-em-maquinas-virtuais-qemu-com-usb-tablet-usb-2.html"><![CDATA[<p>Testando as instalações de máquinas virtuais no libvirt (KVM/QEMU), me deparei com um consumo anormal de CPU no Windows XP e Windows 7, mesmo com o sistema ocioso. “Anormal” para mim, neste caso, era mais ou menos 10% reportado pelo libvirt, enquanto que pelo sistema operacional convidado era 1%.</p>

<p><img src="/assets/libvirt-winxp-1.png" alt="Windows XP - Consumo de CPU reportado pelo libvirt" />
<img src="/assets/libvirt-winxp-2.png" alt="Windows XP - Consumo de CPU reportado pelo Windows" />
<img src="/assets/libvirt-win7-1.png" alt="Windows 7 - Consumo de CPU reportado pelo libvirt" />
<img src="/assets/libvirt-win7-2.png" alt="Windows 7 - Consumo de CPU reportado pelo Windows" /></p>

<p>Revisando as configurações das máquinas, resolvi mudar o controlador USB de <code class="language-plaintext highlighter-rouge">USB 2</code> para <code class="language-plaintext highlighter-rouge">USB 3</code>. O resultado inicial foi que o ponteiro do mouse deixou de funcionar de forma suave (passou a funcionar no modo relativo, não-absoluto), mas o consumo de CPU voltou ao nível esperado.</p>

<p><img src="/assets/libvirt-winxp-3.png" alt="Windows XP - Consumo de CPU normalizado após mudança no controlador USB" />
<img src="/assets/libvirt-win7-3.png" alt="Windows 7 - Consumo de CPU normalizado após mudança no controlador USB" /></p>

<h1 id="usb-tablet--usb-2"><code class="language-plaintext highlighter-rouge">usb-tablet</code> + USB 2</h1>

<p><a href="https://www.kraxel.org/blog/2014/03/qemu-and-usb-tablet-cpu-consumtion/">Em 2014 o Gerd Hoffmann fez um post explicando esta anormalidade quando se usa o dispositivo <code class="language-plaintext highlighter-rouge">usb-tablet</code> num controlador USB 2.</a></p>

<p>Para contornar a situação, é preciso mudar o controlador USB para um que tenha suporte ao <a href="https://en.wikipedia.org/wiki/Extensible_Host_Controller_Interface">xHCI</a> (eXtensible Host Controller Interface, ou simplesmente “USB 3”). Isso explica porque minha mudança de início deu certo. Mas o Windows só oferece suporte nativo ao xHCI a partir do Windows 8, e não existem drivers disponíveis do controlador USB 3 padrão do QEMU, modelo <code class="language-plaintext highlighter-rouge">qemu-xhci</code> (ID de hardware <code class="language-plaintext highlighter-rouge">PCI\VEN_1B36\DEV_000D</code>), para Windows XP e Windows 7.</p>

<p><img src="/assets/libvirt-winxp-4.png" alt="Windows XP - Controlador USB sem driver reconhecido" />
<img src="/assets/libvirt-win7-4.png" alt="Windows 7 - Controlador USB sem driver reconhecido" /></p>

<h2 id="spice-guest-tools">SPICE guest tools</h2>

<p>O ponteiro do mouse volta a ter um comportamento normal instalando o <a href="https://www.spice-space.org/download.html#windows-binaries">SPICE guest tools</a>, mesmo sem um dispositivo <code class="language-plaintext highlighter-rouge">usb-tablet</code> funcional.</p>

<p>Portanto, se você não vai precisar de dispositivos USB emulados ou redirecionados, aqui jaz o problema.</p>

<h1 id="nec-xhci"><code class="language-plaintext highlighter-rouge">nec-xhci</code></h1>

<p>Se você for utilizar dispositivos USB, a boa notícia é que o QEMU pode emular um controlador xHCI no qual existem drivers disponíveis para o Windows XP e Windows 7: o modelo <code class="language-plaintext highlighter-rouge">nec-xhci</code>, ou <strong>NEC Electronics (Renesas) USB 3.0 Host Controller</strong> (ID de hardware <code class="language-plaintext highlighter-rouge">PCI\VEN_1033\DEV_0194</code>).</p>

<p>Para adicioná-lo à máquina virtual, mude o atributo do modelo de controlador USB para <code class="language-plaintext highlighter-rouge">nec-xhci</code>. Usando o <em>virt-manager</em>, no momento em que você aplicar a mudança ele exibirá <code class="language-plaintext highlighter-rouge">USB 3</code> no campo, mas internamente esta propriedade foi alterada para <code class="language-plaintext highlighter-rouge">nec-xhci</code>.</p>

<p><img src="/assets/libvirt-nec-xhci-1.png" alt="virt-manager - Mudando o modelo do controlador USB para nec-xhci" />
<img src="/assets/libvirt-nec-xhci-2.png" alt="virt-manager - Controlador USB alterado internamente para nec-xhci" /></p>

<h2 id="download-dos-drivers-para-o-nec-xhci">Download dos drivers para o <code class="language-plaintext highlighter-rouge">nec-xhci</code></h2>

<p>O site da Dell tem uma página de download para o driver deste controlador: https://www.dell.com/support/home/pt-br/drivers/driversdetails?driverid=36x7d</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th><a href="https://dl.dell.com/FOLDER00364132M/12/DRVR_Chipset_NEC_USB3_A02-36X7D_setup_ZPE.exe">DRVR_Chipset_NEC_USB3_A02-36X7D_setup_ZPE.exe</a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>MD5</td>
      <td>c96dfefc2018ca1cc8f0f194ce5c386c</td>
    </tr>
    <tr>
      <td>SHA1</td>
      <td>12bfa3ff98753ec49cf477745ab993f4d969d2dd</td>
    </tr>
    <tr>
      <td>SHA-256</td>
      <td>6f7efc66f196c4c0cdc8121194c6ba2542cd0a4134f131fec33a5cf02827e724</td>
    </tr>
  </tbody>
</table>

<p>E existe uma outra versão deste driver que aparentemente era distribuída pela Intel, de acordo com o pacote <a href="https://community.chocolatey.org/packages/renesas-usb-3-0-driver">renesas-usb-3-0-driver</a> do Chocolatey.</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th><a href="https://downloadmirror.intel.com/19880/eng/USB3.0_allOS_2.1.28.1_PV.exe">USB3.0_allOS_2.1.28.1_PV.exe</a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SHA-256</td>
      <td>8d13f085128f27c446664b1847efebd02f5383743fd053a9ae6dd05a4c49327d</td>
    </tr>
  </tbody>
</table>]]></content><author><name>Allan</name></author><category term="libvirt" /><category term="kvm" /><category term="qemu" /><category term="windows" /><summary type="html"><![CDATA[Testando as instalações de máquinas virtuais no libvirt (KVM/QEMU), me deparei com um consumo anormal de CPU no Windows XP e Windows 7, mesmo com o sistema ocioso. “Anormal” para mim, neste caso, era mais ou menos 10% reportado pelo libvirt, enquanto que pelo sistema operacional convidado era 1%.]]></summary></entry><entry><title type="html">Chrome Remote Terminal - Chrome Remote Desktop mínimo no Linux</title><link href="https://allan.eti.br/2021/12/06/chrome-remote-terminal.html" rel="alternate" type="text/html" title="Chrome Remote Terminal - Chrome Remote Desktop mínimo no Linux" /><published>2021-12-06T00:00:00+00:00</published><updated>2021-12-06T00:00:00+00:00</updated><id>https://allan.eti.br/2021/12/06/chrome-remote-terminal</id><content type="html" xml:base="https://allan.eti.br/2021/12/06/chrome-remote-terminal.html"><![CDATA[<p>O <a href="https://remotedesktop.google.com/">Chrome Remote Desktop</a>, ou “Área de trabalho remota do Google Chrome”, é uma excelente ferramenta de acesso remoto disponível para Windows, Linux e MacOS.</p>

<p>Mas existem ocasiões em que você não necessita de um ambiente desktop completo para acessar remotamente. Que tal tentar configurar um ambiente Linux com o mínimo consumo de recursos possível para ter um “Chrome Remote Terminal”?</p>

<p>Como o <em>Chromoting</em> para Linux é distribuído num pacote <strong>.deb</strong>, idealmente você deve ter uma máquina rodando o <a href="https://www.debian.org/">Debian</a>. Como sugestão, instale um sistema bem mínimo apenas com o básico do necessário a partir do <a href="https://www.debian.org/CD/netinst/index.en.html">Debian netinst CD image</a>.</p>

<p>Depois que o sistema básico estiver instalado, é hora de instalar o Chrome Remote Desktop, um gerenciador de janelas e um emulador de terminal. Para os dois últimos, as opções que julgo serem as mais apropriadas (e mínimas) são o <a href="https://www.yoctoproject.org/software-item/matchbox/">Matchbox</a> e o <a href="https://st.suckless.org/">st</a>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Baixar e instalar o Chrome Remote Desktop</span>
wget https://dl.google.com/linux/direct/chrome-remote-desktop_current_amd64.deb
<span class="nb">sudo </span>apt-get <span class="nb">install</span> <span class="nt">--assume-yes</span> ./chrome-remote-desktop_current_amd64.deb
<span class="c"># Instalar o Matchbox e o st</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>matchbox-window-manager stterm
<span class="c"># Configurar a sessão do Chromoting</span>
<span class="nb">sudo </span>bash <span class="nt">-c</span> <span class="s1">'echo "exec matchbox-window-manager -use_titlebar no &amp; st" &gt; /etc/chrome-remote-desktop-session'</span>
</code></pre></div></div>

<p>Por fim, vincule o sistema com sua conta do Google seguindo as instruções na página <a href="https://remotedesktop.google.com/headless">https://remotedesktop.google.com/headless</a></p>

<hr />

<p>Leitura complementar: <a href="https://cloud.google.com/architecture/chrome-desktop-remote-on-compute-engine">Setting up Chrome Remote Desktop for Linux on Compute Engine</a></p>]]></content><author><name>Allan</name></author><category term="linux" /><category term="chrome" /><category term="remote" /><category term="desktop" /><summary type="html"><![CDATA[O Chrome Remote Desktop, ou “Área de trabalho remota do Google Chrome”, é uma excelente ferramenta de acesso remoto disponível para Windows, Linux e MacOS.]]></summary></entry><entry><title type="html">eXtreme Go Horse (XGH)</title><link href="https://allan.eti.br/2021/03/08/extreme-go-horse-xgh.html" rel="alternate" type="text/html" title="eXtreme Go Horse (XGH)" /><published>2021-03-08T00:00:00+00:00</published><updated>2021-03-08T00:00:00+00:00</updated><id>https://allan.eti.br/2021/03/08/extreme-go-horse-xgh</id><content type="html" xml:base="https://allan.eti.br/2021/03/08/extreme-go-horse-xgh.html"><![CDATA[<h3 id="1--pensou-não-é-xgh">1- Pensou, não é XGH.</h3>

<p>XGH não pensa, faz a primeira coisa que vem à mente. Não existe segunda opção, a única opção é a mais rápida.</p>

<h3 id="2--existem-3-formas-de-se-resolver-um-problema-a-correta-a-errada-e-a-xgh-que-é-igual-à-errada-só-que-mais-rápida">2- Existem 3 formas de se resolver um problema, a correta, a errada e a XGH, que é igual à errada, só que mais rápida.</h3>

<p>XGH é mais rápido que qualquer metodologia de desenvolvimento de software que você conhece (<a href="#14--xgh-é-atemporal">Vide Axioma 14</a>).</p>

<h3 id="3--quanto-mais-xgh-você-faz-mais-precisará-fazer">3- Quanto mais XGH você faz, mais precisará fazer.</h3>

<p>Para cada problema resolvido usando XGH, mais uns 7 são criados. Mas todos eles serão resolvidos da forma XGH. XGH tende ao infinito.</p>

<h3 id="4--xgh-é-totalmente-reativo">4- XGH é totalmente reativo.</h3>

<p>Os erros só existem quando aparecem.</p>

<h3 id="5--xgh-vale-tudo-só-não-vale-dar-o-toba">5- XGH vale tudo, só não vale dar o toba.</h3>

<p>Resolveu o problema? Compilou? Commit e era isso.</p>

<h3 id="6--commit-sempre-antes-de-update">6- Commit sempre antes de update.</h3>

<p>Se der merda, a sua parte estará sempre correta.. e seus colegas que se fodam.</p>

<h3 id="7--xgh-não-tem-prazo">7- XGH não tem prazo.</h3>

<p>Os prazos passados pelo seu cliente são meros detalhes. Você SEMPRE conseguirá implementar TUDO no tempo necessário (nem que isso implique em acessar o BD por um script malaco).</p>

<h3 id="8--esteja-preparado-para-pular-fora-quando-o-barco-começar-a-afundar-ou-coloque-a-culpa-em-alguém-ou-algo">8- Esteja preparado para pular fora quando o barco começar a afundar… ou coloque a culpa em alguém ou algo.</h3>

<p>Pra quem usa XGH, um dia o barco afunda. Quanto mais o tempo passa, mais o sistema vira um monstro. O dia que a casa cair, é melhor seu curriculum estar cadastrado na APInfo, ou ter algo pra colocar a culpa.</p>

<h3 id="9--seja-autêntico-xgh-não-respeita-padrões">9- Seja autêntico, XGH não respeita padrões.</h3>

<p>Escreva o código como você bem entender, se resolver o problema, commit e era isso.</p>

<h3 id="10--não-existe-refactoring-apenas-rework">10- Não existe refactoring, apenas rework.</h3>

<p>Se der merda, refaça um XGH rápido que solucione o problema. O dia que o rework implicar em reescrever a aplicação toda, pule fora, o barco irá afundar (<a href="#8--esteja-preparado-para-pular-fora-quando-o-barco-começar-a-afundar-ou-coloque-a-culpa-em-alguém-ou-algo">Vide Axioma 8</a>).</p>

<h3 id="11--xgh-é-totalmente-anárquico">11- XGH é totalmente anárquico.</h3>

<p>A figura de um gerente de projeto é totalmente descartável. Não tem dono, cada um faz o que quiser na hora que os problemas e requisitos vão surgindo (<a href="#4--xgh-é-totalmente-reativo">Vide Axioma 4</a>).</p>

<h3 id="12--se-iluda-sempre-com-promessas-de-melhorias">12- Se iluda sempre com promessas de melhorias.</h3>

<p>Colocar TODO no código como uma promessa de melhoria ajuda o desenvolvedor XGH a não sentir remorso ou culpa pela cagada que fez. É claro que o refactoring nunca será feito (<a href="#10--não-existe-refactoring-apenas-rework">Vide Axioma 10</a>).</p>

<h3 id="13--xgh-é-absoluto-não-se-prende-à-coisas-relativas">13- XGH é absoluto, não se prende à coisas relativas.</h3>

<p>Prazo e custo são absolutos, qualidade é totalmente relativa. Jamais pense na qualidade e sim no menor tempo que a solução será implementada, aliás… não pense, faça!</p>

<h3 id="14--xgh-é-atemporal">14- XGH é atemporal.</h3>

<p>Scrum, XP… tudo isso é modinha. O XGH não se prende às modinhas do momento, isso é coisa de viado. XGH sempre foi e sempre será usado por aqueles que desprezam a qualidade.</p>

<h3 id="15--xgh-nem-sempre-é-pog">15- XGH nem sempre é POG.</h3>

<p>Muitas POG’s exigem um raciocínio muito elevado, XGH não raciocina (<a href="#1--pensou-não-é-xgh">Vide Axioma 1</a>).</p>

<h3 id="16--não-tente-remar-contra-a-maré">16- Não tente remar contra a maré.</h3>

<p>Caso seus colegas de trabalho usam XGH para programar e você é um coxinha que gosta de fazer as coisas certinhas, esqueça! Pra cada Design Pattern que você usa corretamente, seus colegas gerarão 10 vezes mais código podre usando XGH.</p>

<h3 id="17--o-xgh-não-é-perigoso-até-surgir-um-pouco-de-ordem">17- O XGH não é perigoso até surgir um pouco de ordem.</h3>

<p>Este axioma é muito complexo, mas sugere que o projeto utilizando XGH está em meio ao caos. Não tente por ordem no XGH (<a href="#16--não-tente-remar-contra-a-maré">Vide Axioma 16</a>), é inútil e você pode jogar um tempo precioso no lixo. Isto fará com que o projeto afunde mais rápido ainda (<a href="#8--esteja-preparado-para-pular-fora-quando-o-barco-começar-a-afundar-ou-coloque-a-culpa-em-alguém-ou-algo">Vide Axioma 8</a>). Não tente gerenciar o XGH, ele é auto suficiente (<a href="#11--xgh-é-totalmente-anárquico">Vide Axioma 11</a>), assim como o caos.</p>

<h3 id="18--o-xgh-é-seu-brother-mas-é-vingativo">18- O XGH é seu brother, mas é vingativo.</h3>

<p>Enquanto você quiser, o XGH sempre estará do seu lado. Mas cuidado, não o abandone. Se começar um sistema utilizando XGH e abandoná-lo para utilizar uma metodologia da moda, você estará fudido. O XGH não permite refactoring (<a href="#10--não-existe-refactoring-apenas-rework">vide axioma 10</a>), e seu novo sistema cheio de frescurites entrará em colapso. E nessa hora, somente o XGH poderá salvá-lo.</p>

<h3 id="19--se-tiver-funcionando-não-rela-a-mão">19- Se tiver funcionando, não rela a mão.</h3>

<p>Nunca altere, e muito menos questione um código funcionando. Isso é perda de tempo, mesmo porque refactoring não existe (<a href="#10--não-existe-refactoring-apenas-rework">Vide Axioma 10</a>). Tempo é a engrenagem que move o XGH e qualidade é um detalhe desprezível.</p>

<h3 id="20--teste-é-para-os-fracos">20- Teste é para os fracos.</h3>

<p>Se você meteu a mão num sistema XGH, é melhor saber o que está fazendo. E se você sabe o que está fazendo, vai testar pra que? Testes são desperdício de tempo, se o código compilar, é o suficiente.</p>

<h3 id="21--acostume-se-ao-sentimento-de-fracasso-iminente">21- Acostume-se ao sentimento de fracasso iminente.</h3>

<p>O fracasso e o sucesso andam sempre de mãos dadas, e no XGH não é diferente. As pessoas costumam achar que as chances do projeto fracassar utilizando XGH são sempre maiores do que ele ser bem sucedido. Mas sucesso e fracasso são uma questão de ponto de vista. O projeto foi por água abaixo mas você aprendeu algo? Então pra você foi um sucesso!</p>

<h3 id="22--o-problema-só-é-seu-quando-seu-nome-está-no-doc-da-classe">22- O problema só é seu quando seu nome está no Doc da classe.</h3>

<p>Nunca ponha a mão numa classe cujo autor não é você. Caso um membro da equipe morra ou fique doente por muito tempo, o barco irá afundar! Nesse caso, utilize o <a href="#8--esteja-preparado-para-pular-fora-quando-o-barco-começar-a-afundar-ou-coloque-a-culpa-em-alguém-ou-algo">Axioma 8</a>.</p>

<hr />

<p><img src="/assets/gohorsenew.jpg" alt="gohorsenew" /></p>

<p>– <a href="https://web.archive.org/web/20110209064356/http://gohorseprocess.wordpress.com/extreme-go-horse-xgh/">Arquivado</a> do original</p>]]></content><author><name>gohorseprocess.wordpress.com</name></author><summary type="html"><![CDATA[1- Pensou, não é XGH.]]></summary></entry><entry><title type="html">IBM Aptiva K23 - Relembrando o meu primeiro computador</title><link href="https://allan.eti.br/2021/02/27/ibm-aptiva-k23.html" rel="alternate" type="text/html" title="IBM Aptiva K23 - Relembrando o meu primeiro computador" /><published>2021-02-27T00:00:00+00:00</published><updated>2021-02-27T00:00:00+00:00</updated><id>https://allan.eti.br/2021/02/27/ibm-aptiva-k23</id><content type="html" xml:base="https://allan.eti.br/2021/02/27/ibm-aptiva-k23.html"><![CDATA[<p>O IBM Aptiva K23 era um computador top de linha em 1996. Você podia adquiri-lo por suaves 19 prestações de R$ 224,00 ou desembolsar à vista R$ 2.999,00.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/sEhYumJiEbY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>E este foi o meu primeiro computador!</p>

<ul>
  <li>Processador Pentium 133MHz</li>
  <li>HDD 1.2 GB</li>
  <li>CD-ROM 8x</li>
  <li>Modem 28.8 Kbps (mas eu só tive internet <em>muito</em> tempo depois)</li>
  <li>Windows 95</li>
</ul>

<p>“Uau!”, você talvez pensaria em 1996. Mas calma. Eu sou (e continuo sendo) pobre; de família pobre. Como que este acabou sendo meu primeiro computador?</p>

<p>Entre 1998 e 1999 minha tia resolveu trocar o seu Aptiva K23 por algum modelo mais atual, e é por isso que ele foi gentilmente doado para minha família. Sou muitíssimo grato por minha tia &amp; família terem me escolhido para receber este computador como doação.</p>

<p>Eu sempre fui bem curioso sobre o funcionamento dele, e em muitas ocasiões eu acabei ferrando bonito a instalação do Windows. Ainda bem que ele veio junto com um CD de recuperação onde eu poderia restaurar o sistema operacional sempre que eu fizesse alguma besteira.</p>

<p><img src="/assets/aptiva-recovery-disk.jpg" alt="Aptiva Recovery Disk" /></p>

<p>Infelizmente, acabei me despedindo do Aptiva K23 em 2005. Nem sei exatamente qual foi o fim que ele teve (RIP). Mas graças ao CD de recuperação da IBM e aos softwares de virtualização, pude rever novamente o sistema que marcou a minha infância.</p>

<h2 id="virtualização">Virtualização</h2>

<p>As opções gratuitas para virtualizar corretamente o Windows 95 que eu vi foram:</p>

<ul>
  <li><a href="https://www.vmware.com/products/workstation-player.html">VMware Workstation Player</a></li>
  <li><a href="https://www.virtualbox.org/">Oracle VirtualBox</a> (versão 6.0 ou inferior, que ainda suportam <em>software virtualization</em>)</li>
  <li><a href="http://bochs.sourceforge.net/">Bochs</a></li>
  <li><a href="https://www.qemu.org/">QEMU</a></li>
  <li><a href="http://pcem-emulator.co.uk/">PCem</a></li>
</ul>

<p>A minha escolha foi o <strong>PCem</strong> porque eu também queria rememorar alguns jogos que eu tinha naquela época.</p>

<p>Como, por exemplo, <em>Rayman Gold</em>:</p>

<p><img src="/assets/rayman-gold_br.jpg" alt="Rayman Gold" /></p>

<p>E o CRÁSSICO <em>3D Pinball Space Cadet</em>:</p>

<p><img src="/assets/3d-pinball-space-cadet.png" alt="Space Cadet" /></p>

<h3 id="restauração-do-sistema">Restauração do sistema</h3>

<p>Para a restauração do sistema, preparei uma máquina no PCem com as seguintes configurações (lembrando das especificações do Aptiva K23):</p>

<ul>
  <li>Machine: [Socket 5] Intel Advanced/EV</li>
  <li>CPU: Intel Pentium 100/66</li>
  <li>Memory: 32 MB</li>
  <li>Graphic device: Cirrus Logic CL-GD5434</li>
  <li>Sound device: Sound Blaster 16</li>
  <li>HDD: Standard IDE (1 GB)</li>
  <li>CD: PCemCD 8x</li>
  <li>Mouse: Microsoft 2-button mouse (serial)</li>
  <li>Network card: none</li>
</ul>

<p>O CD de recuperação tem uma imagem de inicialização semelhante ao disquete de boot do Windows 95, mas o programa de instalação faz algumas checagens para ver se a versão da BIOS bate com os modelos da IBM Aptiva. Por isso, usei a imagem de um disquete de boot do Windows 95 à parte. Depois disso, foi só seguir os passos comuns pré-instalação do Windows 95:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">fdisk</code>
    <ul>
      <li>Criar nova partição primária e ativa</li>
    </ul>
  </li>
  <li>Reiniciar</li>
  <li><code class="language-plaintext highlighter-rouge">format c:</code></li>
</ul>

<p>Após fuçar o arquivo <code class="language-plaintext highlighter-rouge">INSTALL.EXE</code> do disco de recuperação, vi que ele executava o <code class="language-plaintext highlighter-rouge">MAKEDIRS.BAT</code> de dentro dele, e depois extraia os arquivos ZIP para o disco local.</p>

<p><img src="/assets/aptiva-1.png" alt="Aptiva 1" /></p>

<p>Reiniciei o computador e assisti o Windows 95 ser instalado junto com os outros componentes da IBM.</p>

<p>Ah, antes de chegar no fim da instalação de todos os componentes acabei me deparando com a tela azul da morte. Mas bastou reiniciar o sistema no modo seguro (no Windows 95 já existia o atalho <code class="language-plaintext highlighter-rouge">F8</code> para dar o menu de inicialização) e excluir o driver do IBM MWave que estava causando o problema.</p>

<p><img src="/assets/aptiva-2.png" alt="Aptiva 2" /></p>

<p><img src="/assets/aptiva-3.png" alt="Aptiva 3" /></p>]]></content><author><name>Allan</name></author><category term="retroday" /><summary type="html"><![CDATA[O IBM Aptiva K23 era um computador top de linha em 1996. Você podia adquiri-lo por suaves 19 prestações de R$ 224,00 ou desembolsar à vista R$ 2.999,00.]]></summary></entry></feed>