Appearance
Проброс 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, дискЧто это даёт на практике:
| Устройство | COMpipe | USB/IP |
|---|---|---|
| ESP32 / Arduino (CH340, CP2102) | Да, с костылями | Да, штатно |
| Автосброс RTS/DTR при прошивке | Нет | Да |
| Скорость 921600 | Нестабильно | Стабильно |
| Bluetooth-адаптер | Нет | Да |
| USB-флешка | Нет | Да |
| Целый USB-контроллер | Нет | Да |
Далее - по шагам, от установки на Windows до автоматизации проброса через systemd, чтобы не вводить команды после каждой перезагрузки.
ШАГ 1. Настройка хоста Windows (Выполняется ОДИН раз)
- Откройте Windows PowerShell от имени Администратора.
- Установите официальную утилиту
usbipd-winчерез пакетный менеджер Windows:powershellПараметрwinget install --id=dorssel.usbipd-win -e --interactive--interactiveоткроет графический установщик, защищая от внезапной перезагрузки. - Обязательно перезагрузите компьютер (хост), чтобы система обновила переменные среды
PATHи запустила службуusbipd.
ШАГ 2. Настройка гостевой ОС Manjaro Linux (Выполняется ОДИН раз)
Команды даны для Manjaro/Arch. Для Debian/Ubuntu замените pacman на apt, для Fedora — на dnf.
Установите инструменты USB/IP:
bash
# Manjaro/Arch
sudo pacman -S linux-tools
# при выборе из группы — пункт usbipbash
# Debian/Ubuntu
sudo apt install linux-tools-generic usbipbash
# 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-2IP хоста - адрес вашей 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.targetbash
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 |
| Устройство не видно в lsusb | usbip 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)
Пока нет комментариев. Будьте первым!