usbcore
模块,该模块负责检测新的USB设备并加载相应的驱动程序。usbcore
Jika pemacu yang sepadan sudah wujud, maka
usbcore
Proses ini termasuk mendaftarkan pemacu peranti USB baharu dengan kernel dan menyatakan ID pengilang peranti, ID produk dan maklumat lain dalam pemacu. Setelah pemandu berjaya didaftarkan, subsistem USB boleh memadankan peranti dengan pemacu yang betul.
Subsistem USB 2.4 mencipta nod peranti
/dev
Penciptaan nod peranti dicapai melalui proses
Selepas pemandu dimaklumkan bahawa peranti baharu dipalamkan, ia akan memulakan peranti. Permulaan mungkin termasuk menetapkan kadar pemindahan peranti, memperuntukkan penimbal memori, dsb. Selepas permulaan peranti selesai, pemacu melaporkan kepada subsistem USB bahawa peranti itu sudah sedia.
Akhir sekali, program ruang pengguna boleh membuka nod peranti dan berkomunikasi dengan peranti. Kebenaran nod peranti biasanya ditetapkan untuk hanya membenarkan akses kepada pengguna akar atau pengguna dalam kumpulan yang berkaitan. Program ruang pengguna boleh menggunakan panggilan sistem (seperti read
和write
) untuk menghantar arahan ke peranti dan menerima data.
Melalui proses ini, sistem Linux boleh mengenal pasti peranti secara automatik dan memuatkan pemacu yang sepadan supaya peranti boleh berfungsi dengan normal. Ini juga sebabnya apabila kami memasangkan peranti USB, kami tidak perlu memasang sebarang pemacu secara manual atau melakukan sebarang operasi lain untuk mula menggunakan peranti secara terus.
Apabila anda memasangkan peranti USB, sistem Linux secara automatik akan melakukan langkah di atas untuk mengenal pasti peranti secara automatik dan memuatkan pemacu yang sepadan supaya peranti boleh berfungsi dengan normal. Mari analisa proses dari peringkat kod.
Di bawah saya akan menerangkan proses pengenalan dan pemuatan peranti USB dalam sistem Linux melalui beberapa kod sampel. Kod sampel ini hanya untuk menerangkan prinsip, kod sebenar akan menjadi lebih kompleks.
Apabila peranti USB dipalamkan ke dalam sistem, isyarat gangguan dijana, yang ditangkap oleh talian gangguan pengawal USB pada pemproses dan diproses oleh subsistem USB kernel. Berikut ialah contoh kod yang menunjukkan cara mengesan pemalam peranti USB dan acara cabut palam:
#include #include int main() { libusb_device **devs; libusb_context *ctx = NULL; int r = libusb_init(&ctx); if (r printf("Failed to initialize libusb\n"); return 1; } // 扫描USB总线并列出所有连接的设备 ssize_t cnt = libusb_get_device_list(ctx, &devs); if (cnt printf("Failed to get device list\n"); return 1; } // 遍历设备列表,检测插入和拔出事件 for (int i = 0; i if (r printf("Failed to get device descriptor\n"); continue; } printf("Vendor ID: 0x%04x, Product ID: 0x%04x\n", desc.idVendor, desc.idProduct); } // 释放设备列表 libusb_free_device_list(devs, 1); // 退出libusb libusb_exit(ctx); return 0; }
Kod ini menggunakan perpustakaan libusb, iaitu pustaka bahasa C yang digunakan untuk mengakses peranti USB. Ia menyediakan API untuk memulakan subsistem USB dan mengimbas bas USB, serta API untuk mengakses peranti USB.
Setelah peranti dikesan sebagai dipasang, subsistem USB cuba memuatkan pemacu yang sesuai. Di bawah ialah contoh kod pemacu, yang bertanggungjawab untuk menyokong peranti storan USB (seperti pemacu kilat USB):
#include #include static struct usb_device_id storage_devices[] = { { USB_DEVICE(0xabcd, 0x1234) }, { USB_DEVICE(0xffff, 0xffff) }, { } }; MODULE_DEVICE_TABLE(usb, storage_devices); static int storage_probe(struct usb_interface *interface, const struct usb_device_id *id) { // 初始化设备并注册 return 0; } static void storage_disconnect(struct usb_interface *interface) { // 释放设备 } static struct usb_driver storage_driver = { .name = "usb-storage", .probe = storage_probe, .disconnect = storage_disconnect, .id_table = storage_devices, }; module_usb_driver(storage_driver);
Kod ini menunjukkan pemacu ringkas yang boleh mengendalikan acara pemalam dan cabut palam untuk peranti storan USB. Apabila memuatkan pemacu, kernel mencari senarai pemacu yang dimuatkan untuk pemacu yang sepadan dengan peranti.
Jika pemacu yang sepadan ditemui, kernel akan menggunakan pemacu itu untuk mengurus peranti. Jika tiada pemacu yang sepadan ditemui, kernel tidak akan memuatkan sebarang pemacu.
Sebaik sahaja pemandu yang sepadan dengan peranti ditemui, pemandu akan dimuatkan dan dimulakan, ia akan cuba untuk memulakan peranti dan mendaftarkannya dengan kernel. Berikut ialah contoh kod yang menunjukkan cara untuk memulakan peranti storan USB dan mendaftarkannya dengan kernel:
static int storage_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(interface); // 获取设备描述符 struct usb_device_descriptor desc; int r = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &desc, sizeof(desc)); if (r "Failed to get device descriptor\n"); return r; } // 打印设备信息 printk(KERN_INFO "USB storage device detected: Vendor ID=0x%04x, Product ID=0x%04x\n", desc.idVendor, desc.idProduct); // 初始化设备并注册到内核 // ... return 0; }
Kod sampel di atas menggunakan fungsi usb_get_descriptor()
函数来获取设备描述符,并使用printk()
kernel untuk merekod maklumat peranti ke dalam log kernel.
Pemandu akan memanggil fungsi permulaan peranti dan mendaftarkannya dengan kernel, tetapi memandangkan proses pemulaan dan pendaftaran peranti berbeza dari peranti ke peranti, bahagian kod ini ditinggalkan di sini.
一旦设备已经被注册到内核,用户空间程序就可以通过设备节点来访问设备。在Linux系统中,设备节点是一种特殊的文件,可以通过标准文件I/O函数来访问。下面是一个示例代码,演示如何打开并读取USB存储设备:
#include #include #include int main() { // 打开设备节点 int fd = open("/dev/sdb", O_RDONLY); if (fd printf("Failed to open device\n"); return 1; } // 读取设备数据 char buf[1024]; ssize_t n = read(fd, buf, sizeof(buf)); if (n printf("Failed to read device\n"); close(fd); return 1; } // 关闭设备节点 close(fd); return 0; }
这段代码使用了标准的文件I/O函数来访问设备节点。在这个例子中,设备节点的路径是/dev/sdb
,这是一个典型的USB存储设备节点。接下来,程序将设备节点作为文件打开,并使用read()
函数从设备中读取数据。一旦完成数据的读取,程序将关闭设备节点并退出。
Linux系统识别USB设备的过程可以分为四个步骤:设备连接、驱动匹配、设备注册和设备访问。当用户将USB设备插入计算机时,内核将通过USB总线来检测设备的插入事件,并尝试查找与设备匹配的驱动程序。一旦找到了匹配的驱动程序,驱动程序将被加载并启动,它将尝试对设备进行初始化,并将其注册到内核。一旦设备已经被注册到内核,用户空间程序就可以通过设备节点来访问设备。
在Linux系统中,驱动程序是非常重要的组成部分,它们负责管理和控制系统中的各种设备。对于USB设备而言,内核提供了一个通用的USB驱动框架,它可以自动检测和加载驱动程序,并为用户提供了一个简单而强大的USB设备访问接口。通过深入理解USB驱动程序的工作原理,我们可以更好地理解Linux系统中设备管理的内部机制,这对于开发和调试设备驱动程序非常有帮助。
Atas ialah kandungan terperinci Bagaimanakah Linux mengenal pasti peranti USB yang saya palamkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!