Cara menetapkan driver USB ke perangkat

30

Pertanyaan ini ada dua:

Pertama, bagaimana Anda melepaskan driver secara manual dari perangkat USB dan melampirkan yang berbeda? Sebagai contoh, saya memiliki perangkat yang ketika terhubung secara otomatis menggunakan driver penyimpanan usb.

output 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
        ...

Saya tidak ingin menggunakan driver penyimpanan usb, jadi dalam aplikasi saya, saya menggunakan libusbperpustakaan untuk melepaskan driver penyimpanan usb dan kemudian saya mengklaim antarmuka. Saya kemudian dapat mengirim data ke dan dari aplikasi yang berjalan di perangkat USB saya dan pada sistem Linux host saya.

Bagaimana Anda melepaskan driver secara manual di luar aplikasi?


Kedua, bagaimana cara saya secara otomatis menetapkan driver untuk dilampirkan pada plugin perangkat? Saat ini saya memiliki pengaturan aturan udev untuk mengatur izin perangkat secara otomatis:

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

Dapatkah saya menggunakan aturan udev untuk menetapkan driver ke antarmuka tertentu pada perangkat USB? Sebagai contoh, jika saya ingin modul usbnet digunakan secara otomatis pada antarmuka 0 dan bukannya penyimpanan usb, apakah itu mungkin di udev?

linsek
sumber
1
Jika bagian dari masalahnya adalah memuat modul yang tepat, lihat Webcam on Angström
Gilles 'SO- stop being evil'
1
Apakah Anda memerlukan semua modul penyimpanan usb? karena jika tidak, Anda dapat memasukkannya ke daftar hitam dan tidak dapat memuat sama sekali.
Hanan N.
@Gilles, saya berhasil memuat LKM. Pertanyaan saya adalah bagaimana cara saya memasangnya secara manual dan otomatis ke perangkat?
linsek
@ Hananan, saat ini saya tidak menggunakan modul usb-storage. Saya mungkin akhirnya perlu memasukkannya ke dalam daftar hitam untuk secara otomatis melampirkan modul yang benar, tetapi pertama-tama saya harus tahu cara melampirkan yang usbnet.
linsek
1
@njozwiak Module usbnettidak akan memuat secara otomatis, karena tidak memiliki informasi tentang perangkat keras, yang dapat menggunakannya. Coba cari driver yang sesuai dan gunakan, misalnya modinfo kalmia,. Pada aliasbaris Anda akan melihat vendor id xxxx dan id produk yyyy sebagai usb:vxxxxpyyyy. Atau Anda dapat mengedit file /lib/modules/kernel_version/modules.usbmap dan untuk HW Anda, Anda dapat menghapus baris, di mana untuk Anda modul penyimpanan-usb HW atau mengubah penyimpanan usb dengan driver net yang tepat. Tetapi setelah depmod -aperubahan ini akan hilang ...
Jan Marek

Jawaban:

20

Untuk bagian pertama dari pertanyaan, saya telah mencari dan tidak dapat menemukan cara yang lebih baik untuk melepaskan driver USB daripada apa yang sudah Anda lakukan dengan libusb.

Adapun bagian kedua dari pertanyaan, udev dapat bereaksi terhadap memuat driver, tetapi tidak memaksa driver tertentu untuk ditugaskan ke perangkat.

Setiap driver di kernel Linux bertanggung jawab untuk satu atau lebih perangkat. Pengemudi itu sendiri memilih perangkat apa yang didukungnya. Ini dilakukan secara terprogram, yaitu dengan memeriksa vendor perangkat dan ID produk, atau, jika itu tidak tersedia (misalnya perangkat lama), melakukan beberapa heuristik deteksi otomatis dan pemeriksaan kewarasan. Setelah driver yakin itu menemukan perangkat yang didukungnya, ia menempelkannya ke sana. Singkatnya, Anda seringkali tidak dapat memaksa pengemudi tertentu untuk menggunakan perangkat tertentu. Namun, kadang-kadang, driver perangkat murah hati dengan apa yang diterimanya, dan perangkat dapat bekerja yang tidak diketahuinya. Jarak tempuh Anda akan bervariasi! Di masa lalu, saya harus secara manual menambahkan perangkat PCI / ID vendor aneh ke driver yang seharusnya mendukung mereka, dengan keberhasilan beragam dan beberapa crash kernel yang lucu.

Sekarang, dalam hal modul, ada langkah ekstra. The Modul loader yang dibangunkan oleh kernel ketika sebuah perangkat baru terdeteksi. Telah melewati string 'modalias', yang mengidentifikasi perangkat dan terlihat seperti ini untuk perangkat USB:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

String ini berisi kelas perangkat ( usb) dan informasi khusus kelas (vendor / perangkat / nomor seri, kelas perangkat, dll). Setiap driver kernel berisi baris seperti:

MODULE_ALIAS("usb:...")

Yang harus cocok dengan usbalias (wildcard digunakan untuk mencocokkan beberapa perangkat). Jika modaliascocok dengan yang didukung oleh driver, driver ini dimuat (atau diberitahukan perangkat baru, jika sudah ada di sana).

Anda dapat melihat perangkat yang didukung (dengan modalias) dan modul yang terkait dengannya

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

Jika Anda menerima driver perangkat penyimpanan-usb, Anda akan melihatnya memiliki beberapa perangkat khusus yang didukung oleh vendor dan ID perangkat, dan juga akan mencoba untuk mendukung perangkat apa pun dengan kelas (penyimpanan) yang tepat, tidak peduli vendor / perangkat .

Anda dapat memengaruhi ini menggunakan mekanisme userspace di OS Anda ( /etc/modprobe.d/di Debian dan teman-teman). Anda dapat membuat daftar hitam modul, atau Anda dapat menentukan modul yang akan dimuat oleh modalias, seperti halnyamodules.alias file (dan menggunakan sintaks yang sama). depmod -akemudian akan membuat ulang pola pemuat modul.

Namun, meskipun Anda bisa menuntun kuda ini ke air, tetapi Anda tidak bisa membuatnya minum. Jika driver tidak memiliki dukungan untuk perangkat Anda, ia harus mengabaikannya.

Ini adalah teori dalam kasus umum.

Dalam praktiknya, dan dalam kasus USB, saya melihat perangkat Anda tampaknya memiliki dua antarmuka , di mana penyimpanan adalah satu. Kernel akan melampirkan ke antarmuka penyimpanan perangkat secara keseluruhan. Jika antarmuka lain memiliki kelas yang tepat, usbnetpengemudi dapat melampirkannya. Ya, Anda dapat memiliki beberapa driver yang terpasang pada perangkat fisik yang sama , karena perangkat USB mengekspor banyak antarmuka (mis. Keyboard Logitech G15 saya mengekspor dua karena memiliki perangkat keyboard dan layar LCD, yang masing-masing ditangani oleh driver terpisah) .

Fakta bahwa antarmuka kedua perangkat USB Anda tidak terdeteksi adalah indikasi kurangnya dukungan di kernel. Apa pun masalahnya, Anda dapat membuat daftar antarmuka perangkat / titik akhir dalam detail yang menyiksa menggunakan lsusb -v | less, lalu gulir ke bawah ke perangkat khusus Anda (Anda dapat membatasi output berdasarkan perangkat: ID vendor atau jalur USB jika Anda cenderung).

Harap dicatat: Saya sedikit menyederhanakan di sini sehubungan dengan struktur logis perangkat USB. Salahkan konsorsium USB. :)

Alexios
sumber
4
Sudah ada static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);dalam kode, apakah itu berlebihan dengan modalias?
Thomas
Dalam kasus saya, garis-garis tersebut di-autogenerasi oleh sihir Makefile di mana saja dalam driver. Itu sebabnya saya menambahkan tiga kali baris untuk MODULE_ALIAS tetapi tidak pernah terdaftar. Pokoknya terima kasih untuk lsusb -v. dengan itu saya bisa memeriksanya dan menemukan kekurangan dalam ide saya. Saya kemudian mengambil sumber untuk pengenal yang dikenal dan menemukan array dengan entri yang harus saya manipulasi.
JackGrinningCat