Skip to content

Проброс USB в Hyper-V к Manjaro Linux через usbipd-win ​

Система мониторинга
👁0просмотров

В последнее время Hyper-V переживает второе рождение. С ним уже не только играются энтузиасты, но и решают вполне рабочие задачи. Свои гипервизоры получили и Linux (KVM), и FreeBSD (bhyve). Но у них у всех есть одна и та же родовая травма - проброс USB-устройств. Hyper-V не исключение.

Да, изоляция и безопасность - это хорошо. Но на практике, постоянно нужно то флешку прочитать, то Bluetooth-адаптер подключить, то мультимедиа-устройство пробросить. А недавно встала задача перепрошить Arduino. Пришлось разбираться.

Оказалось, что при всей своей закрытости Hyper-V всё-таки позволяет пробрасывать порты. Первым делом я попробовал COMpipe - стороннюю утилиту для проброса последовательного порта через именованный канал. Manjaro увидел ESP32, плата даже пыталась что-то принять. Но тут же начали вылезать ограничения - и не COMpipe, а самого канала Hyper-V.

Первое ограничение - аппаратные сигналы. RTS/CTS, DTR/DSR, DCD и RI через именованный канал не передаются. Пришлось идти на костыль: замкнул GPIO0 на землю, один раз нажал RESET - плата вошла в режим прошивки.

Второе ограничение - поток данных. На первом же блоке записи вылезла ошибка:

text
Failed to write compressed data to flash after seq 0 
(result was C000: Bad data length)

Пакет со сжатым файлом искажался где-то на пути через сетевой стек именованного канала. Причина в том, что физический COM-порт работает побайтово, а именованный канал Windows передаёт данные блоками. Это ломает алгоритм аппаратного сжатия esptool. Чтобы завершить прошивку, нужно было отключить сжатие при отправке, причем навсегда в файле библиотеки.

Стало понятно, что COMpipe - это полумера, которая упирается в архитектуру. И я пошёл другим путём - пробросом USB-контроллера целиком через USB/IP.

От COMpipe к USB/IP ​

COMpipe дал ценный опыт. Он показал, где именно проходит граница возможностей именованного канала. Дальше двигаться в эту сторону было бессмысленно - пришлось бы городить костыли на костылях, отключать сжатие, вручную дёргать RESET, мириться с нестабильностью на высоких скоростях. Для одной платы это ещё терпимо. Для рабочего процесса - нет.

Нужно было решение, которое пробрасывает USB-устройство целиком, а не отдельный его интерфейс. Чтобы работали и DTR/RTS, и любая скорость, и любые устройства - не только ESP32, но и Bluetooth, флешки, отладочные платы, целые контроллеры.

Такое решение есть, и его создала сама Microsoft. Называется USB/IP - протокол, который передаёт USB-трафик по сети. На Windows-хосте работает официальная утилита usbipd-win, в Linux-госте - стандартный usbip из ядра. Вместо виртуального COM-порта, зажатого в рамки именованного канала, в гостя уходит весь USB-контроллер со всеми его сигналами и устройствами.

Схема простая:

text
Windows (usbipd-win)  ←—— USB/IP по сети ——→  Linux-гость (usbip)
     ↑                                              ↑
физическое USB-устройство                  /dev/ttyUSB0, Bluetooth, диск

Что это даёт на практике:

УстройствоCOMpipeUSB/IP
ESP32 / Arduino (CH340, CP2102)Да, с костылямиДа, штатно
Автосброс RTS/DTR при прошивкеНетДа
Скорость 921600НестабильноСтабильно
Bluetooth-адаптерНетДа
USB-флешкаНетДа
Целый USB-контроллерНетДа

Далее - по шагам, от установки на Windows до автоматизации проброса через systemd, чтобы не вводить команды после каждой перезагрузки.

ШАГ 1. Настройка хоста Windows (Выполняется ОДИН раз) ​

  1. Откройте Windows PowerShell от имени Администратора.
  2. Установите официальную утилиту usbipd-win через пакетный менеджер Windows:
    powershell
    winget install --id=dorssel.usbipd-win -e --interactive
    Параметр --interactive откроет графический установщик, защищая от внезапной перезагрузки.
  3. Обязательно перезагрузите компьютер (хост), чтобы система обновила переменные среды PATH и запустила службу usbipd.

ШАГ 2. Настройка гостевой ОС Manjaro Linux (Выполняется ОДИН раз) ​

Команды даны для Manjaro/Arch. Для Debian/Ubuntu замените pacman на apt, для Fedora — на dnf.

Установите инструменты USB/IP:

bash
# Manjaro/Arch
sudo pacman -S linux-tools
# при выборе из группы — пункт usbip
bash
# Debian/Ubuntu
sudo apt install linux-tools-generic usbip
bash
# Fedora
sudo dnf install usbip

Добавьте пользователя в группы доступа к портам:

bash
sudo usermod -aG uucp,dialout,lock $USER

Перезапустите VM, чтобы права применились.

Проверьте, что модуль vhci-hcd загружается:

bash
sudo modprobe vhci-hcd
lsmod | grep vhci

ШАГ 3. Ежедневный проброс (выполняется при каждом подключении) ​

3.1. На Windows ​

Подключите USB-устройство к компьютеру.

Откройте PowerShell от имени Администратора и выведите список устройств:

powershell
usbipd list

В выводе найдите нужное устройство - например, USB-SERIAL CH340 - и запомните его BUSID (например, 1-2).

Откройте общий доступ к устройству:

powershell
usbipd bind --busid 1-2 --force

Флаг --force нужен, если устройство перехвачено фильтром антивируса (например, klfltdev у Касперского).

Прикрепите устройство к USB/IP-серверу:

powershell
usbipd attach --wsl --busid 1-2

Флаг --wsl в этой команде технически означает «прикрепить к хосту USB/IP-сервера; гость подключается к нему по сети отдельно.

3.2 В Linux-госте ​

Загрузите драйвер виртуального USB-контроллера:

bash
sudo modprobe vhci-hcd

Подключите устройство с хоста:

powershell
sudo usbip attach --remote=192.168.0.65 --busid=1-2

IP хоста - адрес вашей Windows-машины в локальной сети, например 192.168.251.65.

Проверьте, что устройство появилось:

bash
lsusb

Для последовательных устройств (ESP32, Arduino) проверьте имя порта:

bash
dmesg | grep ttyUSB

Обычно это /dev/ttyUSB0.

ШАГ 4. Примеры для разных типов устройств ​

ESP32 / Arduino (CH340, CP2102) ​

После проброса порт появится как /dev/ttyUSB0. В Arduino IDE:

  • Плата: ESP32 Dev Module (или ваша).
  • Порт: /dev/ttyUSB0.
  • Upload Speed: 921600.

Автосброс RTS/DTR работает полностью - кнопки на плате нажимать не нужно. Именно то, чего не хватало при работе через COMpipe.

Bluetooth-адаптер ​

После attach адаптер появится в системе как локальный:

bash
bluetoothctl list
bluetoothctl power on

Дальше - стандартная работа: сканирование, спаривание, подключение устройств.

USB-флешка ​

bash
lsblk
sudo mount /dev/sdX1 /mnt

Важно: не монтируйте на хосте, иначе устройство будет занято и проброс не сработает.

Целый USB-контроллер ​

Если нужно пробросить все устройства на одном контроллере разом, найдите в usbipd list сам контроллер (обычно это строка с несколькими устройствами) и привяжите его BUSID. Тогда в гость уйдут все подключённые к нему устройства.

ШАГ 5. Автоматизация: systemd-юнит в госте ​

Чтобы не вводить usbip attach после каждой перезагрузки, создайте unit:

ini
# /etc/systemd/system/usbip-attach.service
[Unit]
Description=USB/IP attach
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/usbip attach --remote=192.168.251.65 --busid=1-2
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
bash
sudo systemctl enable --now usbip-attach.service

Если устройство может отсутствовать при загрузке, добавьте Restart=on-failure и RestartSec=5 - сервис будет повторять попытку.

ШАГ 6. Troubleshooting ​

ПроблемаРешение
usbip: command not foundУстановите linux-tools (Arch) / usbip (Debian)
vhci-hcd не загружаетсяsudo modprobe vhci-hcd, проверьте lsmod
Устройство не видно в lsusbusbip list --remote=IP — видит ли хост устройства
bind падает с ошибкойУстройство занято драйвером хоста — отключите в Диспетчере устройств
После обновления Windows bind слетелПовторите usbipd bind
Устройство пропало после перезагрузки гостяattach нужно повторять (или используйте systemd)
Ошибка Bad data lengthЭто COMpipe; в USB/IP не встречается

ШАГ 7. Сравнение с альтернативами ​

РешениеПлюсыМинусы
COMpipeПросто, работает для COMТолько COM, нет RTS/DTR, искажение потока, ограничения Gen-2
USB/IP (usbipd-win)Бесплатно, официально от Microsoft, любые USB, полные сигналыТребует сети, attach после перезагрузки
USB Network Gate / FlexiHubКроссплатформенно, GUIПлатно
Physical Disk PassthroughПросто для флешекТолько mass storage

Вывод

USB passthrough в Hyper-V возможен - но не через GUI и не через COMpipe. Рабочий путь - USB/IP и официальная утилита usbipd-win. Это закрывает потребность целиком: от ESP32 и Arduino до Bluetooth-адаптеров, флешек и целых контроллеров. Один раз настроил - дальше автоматизируется через systemd.

COMpipe решает частную задачу и упирается в архитектуру. USB/IP решает проблему.

Как вам статья?

ℹ️ Вы можете выбрать любую реакцию (доступен один голос на статью).

Обсуждение статьи (0)

Пока нет комментариев. Будьте первым!

Released under the MIT License.