Як призначити драйвер USB до пристрою


30

Це запитання двояке:

По-перше, як ви вручну від'єднати драйвер від USB-пристрою та приєднати інший? Наприклад, у мене є пристрій, який при підключенні автоматично використовує драйвер зберігання usb.

usbview вихід

Vendor Id: xxxx
Product Id: xxxx
...
    Number of Interfaces: 2
    Interface Number: 0
        Name: usb-storage
        Number of Endpoints: 2
        ...
    Interface Number: 1
        Name: (none)
        Number of Endpoints: 2
        ...

Я не хочу використовувати драйвер USB-накопичувача, тому у своїй програмі я використовую libusbбібліотеку, щоб від'єднати драйвер usb-сховища, а потім вимагаю інтерфейс. Потім я можу надсилати дані до та із програм, що працюють на моєму USB-пристрої та в моїй хост-системі Linux.

Як від'єднати драйвер вручну поза програми?


По-друге, як я автоматично призначу драйверу приєднувати плагін пристрою? Наразі у мене є настройка правила udev, щоб автоматично встановлювати дозволи пристрою:

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

Чи можу я використовувати правила udev для призначення драйверів певним інтерфейсам на USB-пристрої? Наприклад, якщо я хотів, щоб модуль usbnet автоматично використовувався на інтерфейсі 0 замість usb-сховища, чи можливо це у udev?


1
Якщо частина проблеми полягає у завантаженні правого модуля, дивіться веб-камеру на Angström
Gilles 'SO- перестаньте бути злим'

1
Вам потрібен взагалі модуль зберігання usb? тому що як ні, ви можете помістити його у чорний список, і він взагалі не завантажиться.
Ханан Н.

@Gilles, я успішно можу завантажити LKM. Моє запитання - як мені вручну та автоматично приєднати це до пристрою?
linsek

@Hanan, на даний момент я не використовую модуль зберігання usb. Можливо, мені в кінцевому підсумку потрібно буде передати його в чорний список, щоб автоматично приєднати правильний модуль, але спочатку мені потрібно знати, як приєднати usbnet.
linsek

1
@njozwiak Модуль usbnetне завантажується автоматично, оскільки він не має інформації про обладнання, яке може ним користуватися. Спробуйте знайти потрібний драйвер і використовувати, наприклад, modinfo kalmia. У aliasрядках ви побачите ідентифікатор постачальника xxxx та ідентифікатор продукту yyyy as usb:vxxxxpyyyy. Або ви можете редагувати файл /lib/modules/kernel_version/modules.usbmap, а для свого HW ви можете видалити рядок, де для вас модуль usb-сховища модуля HW або змінити usbstorage з належним чистим драйвером. Але після depmod -aцього зміна піде ...
Ян Марек

Відповіді:


20

У першій частині питання я шукав і не міг знайти кращого способу від'єднати USB-драйвер, ніж те, що ви вже робите з libusb.

Що стосується другої частини питання, udev може реагувати на завантаження драйверів, але не примушувати конкретного драйвера призначати пристрою.

Кожен драйвер ядра Linux відповідає за один або кілька пристроїв. Драйвер сам вибирає, які пристрої він підтримує. Це робиться програмно, тобто перевіряючи постачальника пристрою та ідентифікатор продукту, або, якщо вони недоступні (наприклад, старий пристрій), виконуючи деякі евристики автоматичного виявлення та перевірки стану безпеки. Як тільки водій впевнений, що знайшов пристрій, який він підтримує, він приєднається до нього. Коротше кажучи, ви часто не можете змусити конкретного драйвера використовувати певний пристрій. Однак іноді драйвер пристрою щедрий на те, що він приймає, і пристрій може працювати, про що він не знає. Ваш пробіг буде змінюватися! Раніше мені довелося вручну додавати дивні ідентифікатори пристрою / постачальника PCI до драйверів, які повинні їх підтримувати, зі змішаним успіхом та кількома забавними збоями ядра.

Тепер, що стосується модулів, є додатковий крок. Модуль завантажувач пробуджується ядром , коли новий пристрій виявлено. Це передано рядок "modalias", який ідентифікує пристрій і виглядає приблизно так для USB-пристроїв:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Цей рядок містить клас пристрою ( usb) та інформацію, що стосується класу (постачальник / пристрій / серійний номер, клас пристрою тощо). Кожен драйвер ядра містить рядок, такий як:

MODULE_ALIAS("usb:...")

Які повинні відповідати usbalias (макіяж використовуються для підбору декількох пристроїв). Якщо modaliasзбігається з підтримкою драйвера, цей драйвер завантажується (або повідомляється про новий пристрій, якщо він вже є).

Ви можете бачити підтримувані пристрої (від modalias) та пов'язані з ними модулі за допомогою

less /lib/modules/`uname -r`/modules.alias

Якщо ви візьметеся за драйвер пристрою зберігання usb, ви побачите, що у нього є деякі конкретні пристрої, які він підтримує за допомогою ідентифікатора постачальника та пристрою, а також намагатиметься підтримувати будь-який пристрій з правильним класом (сховище), незалежно від постачальника / пристрою .

Ви можете впливати на це, використовуючи механізми простору користувача на вашій ОС ( /etc/modprobe.d/на Debian та друзів). Ви можете переглядати модулі чорного списку, або ви можете вказати модулі для завантаження modalias, як і modules.aliasфайл (і використовуючи той самий синтаксис). depmod -aпотім відновить схеми завантажувача модулів.

Однак, навіть якщо ви можете вести цього конкретного коня до води, але ви не можете змусити його пити. Якщо у драйвера немає підтримки для вашого пристрою, він повинен ігнорувати його.

Це теорія в загальному випадку.

На практиці, і що стосується USB, я бачу, що ваш пристрій має два інтерфейси , один із яких - це сховище. Ядро буде приєднано до інтерфейсу зберігання загального пристрою. Якщо інший інтерфейс має правильний клас, usbnetдрайвер може приєднатися до нього. Так, ви можете мати декілька драйверів, підключених до одного фізичного пристрою, тому що USB-пристрій експортує кілька інтерфейсів (наприклад, моя клавіатура Logitech G15 експортує два, оскільки має клавіатурний пристрій та РК-екран, кожен з яких обробляється окремим драйвером) .

Те, що другий інтерфейс вашого USB-пристрою не виявлено, свідчить про відсутність підтримки в ядрі. Незалежно від цього, ви можете перелічити інтерфейси / кінцеві точки пристрою з неприємними деталями, використовуючи lsusb -v | lessпотім, прокрутіть униз до конкретного пристрою (ви можете обмежити вихід за допомогою пристрою: ідентифікатор постачальника або шлях USB, якщо ви так схильні).

Зверніть увагу: я тут трохи спрощую логічну структуру USB-пристроїв. Звинувачуйте консорціум USB. :)


4
У static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);коді вже є, чи він зайвий з модаліями?
Томас

У моєму випадку ці лінії автоматично створюються деякою магією Makefile в будь-якому місці драйвера. Ось чому я додав тричі рядки для MODULE_ALIAS, але він ніколи не потрапляє до списку. У будь-якому випадку дякую за lsusb -v. з цим я міг це перевірити і знайти недолік у своїй ідеї. Потім я перебираю джерело за відомим ідентифікатором і знайшов масив із записами, якими мені довелося маніпулювати.
JackGrinningCat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.