SantyagoSantyago
Avatar

Witaj!
Blog archiwalny. Już niebawem nowy serwis!

YouTube RSS Facebook GitHub

Jakiś czas temu stałem się posiadaczem karty AVerMedia Live Gamer HD Lite do przechwytywania sygnału HDMI w rozdzielczości FullHD z prędkością 30fps. Głównie mam ją zamiar wykorzystywać do nagrywania materiałów z mini komputerów z układami SoC (Odroid/Marsboard/Cubieboard itp.), gdzie nagrywanie obrazu bezpośrednio z uruchomionego systemu jest praktycznie niemożliwe.

Na upartego problem mnie nie dotyczył, ponieważ zawsze mogę przełączyć się na Windowsa i tam nagrać materiał bezpośrednio z karty graficznej czy dowolnego urządzenia, ale problem pojawił się, gdy chciałem przechwycić w miarę płynny film z pulpitu Linuksa pod większym obciążeniem. Dodatkowo, każdy kto próbował nagrać rozgrywkę gry wykorzystującej OpenGL i tryb pełnoekranowy wie, że to droga przez mękę, która w większości przypadków kończy się niepowodzeniem lub fatalną ilością klatek na sekundę. Gdyby AVerMedia Live Gamer HD / Lite był obsługiwany pod Linuksem, nie było by w ogóle tematu, a tak trzeba sobie jakoś radzić na około. Z pomocą przychodzi nam wirtualizacja.

Wymagania

Do tej sztuczki będzie nam potrzebny procesor z obsługą AMD-VI/VT-D oraz jądro 2.15 z włączoną obsługą IOMMU / KVM oraz nałożoną łatką acs override. Oczywiście nie obejdzie się bez 64-bitowego Windowsa 7 lub 8 i QEMU 2.0. Jeśli macie pecha tak jak ja i posiadacie na płycie głównej kontroler SATA Marvel 88SE91xx to napotkacie problem z dostępem DMA przy włączonej opcji iommu.

  1. ata8: SATA max UDMA/133 abar m2048@0xfa310000 port 0xfa310180 irq 48
  2. ata8: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
  3. ata8.00: qc timeout (cmd 0xec)
  4. ata8.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  5. ata8: SATA link up 6.0 Gbps (SStatus 133 SControl 300)

Problem można rozwiązać wyłączając ten kontroler w BIOS-ie (jeśli z niego nie korzystacie, ja niestety mam podłączony pod niego trzeci dysk twardy) lub nakładając łatki dma-alias-v4. Dlaczego o tym wspominam? Po pierwsze, możesz posiadać taki kontroler na swojej płycie. Po drugie, problem ten może pojawić się z innymi specyficznymi urządzeniami. Zalecam zatem sprawdzić na początek działanie iommu tylko z nałożoną łatką acs override. Osobiście nie doświadczyłem negatywnych skutków działania tej łaty na innych systemach, nawet kiedy nie jest potrzebna.

Uruchomienie jądra z obsługą IOMMU i ACS

Do parametrów tak skompilowanego jądra dołączamy następujące opcje:

intel_iommu=on pci-stub.ids=1af2:a001 pcie_acs_override=downstream

Jeśli posiadasz procesor AMD to intel_iommu zamieniamy na amd_iomu. Użyty identyfikator 1af2:a001 to VendorID oraz ProductID naszej karty. Zweryfikować to można za pomocą polecenia lspci:

  1. # lspci
  2. 02:00.0 Unassigned class [ff00]: Device 1af2:a001

W ten sposób "odłączamy" ją z systemu hosta. Sprawdźmy zatem, czy po ponownym uruchomieniu wszystko jest jak należy:

  1. dmesg | grep dmar
  2. [    0.049835] dmar: Host address width 36
  3. [    0.049839] dmar: DRHD base: 0x000000fed91000 flags: 0x1
  4. [    0.049848] dmar: IOMMU 0: reg_base_addr fed91000 ver 1:0 cap c9008020660262 ecap f0105a
  5. [    0.049851] dmar: RMRR base: 0x000000bf4cc000 end: 0x000000bf4eefff
  1. # dmesg | grep -i iommu
  2. [    0.000000] Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA
  3. [    0.000000] Intel-IOMMU: enabled
  4. [    0.049848] dmar: IOMMU 0: reg_base_addr fed91000 ver 1:0 cap c9008020660262 ecap f0105a
  5. [    0.049921] IOAPIC id 0 under DRHD base  0xfed91000 IOMMU 0
  6. [    0.243132] IOMMU 0 0xfed91000: using Queued invalidation
  7. [    0.243135] IOMMU: Setting RMRR:
  8. [    0.243144] IOMMU: Setting identity map for device 0000:00:1a.0 [0xbf4cc000 - 0xbf4eefff]
  9. [    0.243163] IOMMU: Setting identity map for device 0000:00:1d.0 [0xbf4cc000 - 0xbf4eefff]
  10. [    0.243173] IOMMU: Prepare 0-16MiB unity mapping for LPC
  11. [    0.243180] IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]
  1. # dmesg | grep pci-stub
  2. [   14.574603] pci-stub: add 1AF2:A001 sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
  3. [   14.574615] pci-stub 0000:02:00.0: claimed by stub

Podłączenie karty AVerMedia Live Gamer HD

Istnieje kilka sposobów podłączenia tej karty. Zalecana metoda to połączenie karty graficznej kablem HDMI do wejścia Input, a monitora do wyjścia Output.

Ja podłączyłem monitor bezpośrednio do karty graficznej kablem DVI, a na obu systemach ustawiłem tryb pracy klonowania. W ten sposób mam ten sam obraz na obu wyjściach, pozostawiając wciąż wolne HDMI w monitorze.

Bindowanie karty do vfio-pci

W następnej kolejności musimy przypisać naszą kartę do vfio-pci. Dla ułatwienia możemy posłużyć się skryptem avermedia.sh

  1. #!/bin/bash
  2.  
  3. modprobe vfio-pci
  4.  
  5. dev=0000:02:00.0
  6. vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
  7. device=$(cat /sys/bus/pci/devices/$dev/device)
  8.  
  9. if [ -e /sys/bus/pci/devices/$dev/driver ]; then
  10.     echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
  11. fi
  12.  
  13. echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id

Zwróć uwagę na zmienną dev zawierającą ciąg 0000:02:00.0  - powinna zwierać identyfikator Twojej szyny PCI do której wpięta jest karta AVerMedia (sprawdzaliśmy to poleceniem lspci)

Uruchamiamy powyższy skrypt:

  1. # chmod 755 +x avermedia.sh
  2. # avermedia.sh

Dla ułatwienia, możemy dodać ten skrypt do rc.local, aby wykonywał się automatycznie przy starcie systemu.

Uruchomienie QEMU

Zakładam, że nie masz jeszcze zainstalowanego Windowsa, więc tworzymy sobie na początek 20GB dysk twardy,

  1. # dd if=/dev/zero of=windows.img bs=1M seek=20000 count=0

Następnie instalujemy Widnowsa:

  1. #qemu-system-x86_64
  2.     -enable-kvm
  3.     -M q35
  4.     -m 2048
  5.     -cpu host
  6.     -smp 2,sockets=1,cores=2,threads=1
  7.     -bios /usr/share/qemu/bios.bin
  8.     -device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1
  9.     -device vfio-pci,host=02:00.0,bus=root.1,addr=00.0,multifunction=on
  10.     -drive file=windows.img,id=disk,format=raw
  11.     -device ide-hd,bus=ide.0,drive=disk
  12.     -drive file=cdwin.iso,id=isocd
  13.     -device ide-cd,bus=ide.1,drive=isocd
  14.     -display sdl -sdl

Dobór parametrów pamięci, ilość dostępnych rdzeni i wątków procesora pozostawiam Wam, ponieważ jest to kwestia indywidualna, zależna od procesora i ilości pamięci RAM jaką posiadamy. Tutaj ponownie sprawdźcie, czy parametr -device vfio-pci,host posiada odpowiedni identyfikator szyny PCI hosta.

Uruchomienie i instalacja sterowników

Po uruchomieniu systemu zobaczymy w menadzerze urządzeń naszą kartę:

Po zainstalowaniu sterowników ze strony producenta, urządzenie powinno być w pełni widoczne:

Teraz nie pozostaje nam już nic innego, jak rozpocząć nagrywanie:

Przykład nagrywania rozgrywki z Anomaly Defenders