Rumah  >  Artikel  >  Tutorial sistem  >  Bagaimanakah Linux mengenal pasti peranti USB yang saya palamkan?

Bagaimanakah Linux mengenal pasti peranti USB yang saya palamkan?

PHPz
PHPzke hadapan
2024-02-09 14:15:15904semak imbas

1 Semasa mempelajari sistem pengendalian Linux, pernahkah anda mempunyai soalan ini: Mengapa komputer kita boleh mengecam dan menggunakan peranti USB yang berbeza? Mengapa sistem Linux tidak menggunakan tetikus sebagai papan kekunci? Mari kita bincangkan proses pengenalpastian dan pemuatan peranti USB dalam sistem Linux.

2. Pengecaman dan pemuatan peranti USB

Apabila kami memasangkan peranti USB ke dalam komputer, kernel Linux secara automatik akan mengesan dan memuatkan pemacu yang sepadan supaya peranti boleh berfungsi dengan baik. Seterusnya, kami akan menyelidiki proses pengenalpastian dan pemuatan peranti USB dalam sistem Linux.

Bagaimanakah Linux mengenal pasti peranti USB yang saya palamkan?2.1 pengawal USB mengesan pemasukan peranti

Pengawal USB ialah peranti perkakasan yang digunakan untuk mengawal peranti pada bas USB. Apabila anda memasangkan peranti USB, pengawal USB mengesan perubahan voltan dan menghantar isyarat gangguan. Isyarat gangguan ini dihantar ke talian gangguan pengawal USB pada pemproses, memberitahu kernel Linux bahawa peranti USB baharu dipasang.

2.2 kernel mengesan dan memuatkan pemacu

Apabila kernel menerima isyarat gangguan daripada pengawal USB, ia akan memanggil modul

dalam subsistem USB untuk mula-mula mengesan deskriptor peranti ini termasuk ID pengeluar peranti, ID produk, kod kategori dan maklumat lain.

usbcore模块,该模块负责检测新的USB设备并加载相应的驱动程序。usbcoreJika pemacu yang sepadan sudah wujud, maka

modul akan memuatkan pemandu ini. Jika tiada pemacu yang sepadan, ia akan cuba memuatkan pemacu universal yang boleh menyokong kebanyakan peranti USB.

usbcore

Pemandu 2.3 mendaftar dengan subsistem USB

Setelah pemacu yang betul dimuatkan, ia mendaftar dengan subsistem USB dan memberitahunya peranti mana yang boleh dikendalikannya. Langkah ini biasanya melibatkan pendaftaran kelas peranti USB (seperti peranti storan, peranti input, dll.) dengan kernel.

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

Subsistem USB seterusnya akan mencipta nod peranti untuk peranti tersebut. Nod peranti ialah fail khas dalam direktori

yang membolehkan program ruang pengguna berkomunikasi dengan peranti. Nama nod peranti biasanya dijana secara dinamik oleh kernel berdasarkan ID pengilang peranti, ID produk, nombor siri dan maklumat lain.

/devPenciptaan nod peranti dicapai melalui proses

daemon, yang memantau pemalam peranti dan mencabut acara dalam sistem dan secara automatik mencipta atau memadamkan nod peranti yang sepadan. Selepas nod peranti dibuat, kernel boleh menetapkan hak akses kepada peranti kepada program ruang pengguna.

Peranti permulaan pemacu 2.5

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.

2.6 Program angkasa pengguna membuka peranti:

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 readwrite) 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.

3. Penerangan pelaksanaan 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.

3.1 Sisipan peranti pengesanan

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.

3.2 Muatkan pemandu

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.

3.3 Pendaftaran Peranti

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.

3.4 设备访问

一旦设备已经被注册到内核,用户空间程序就可以通过设备节点来访问设备。在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!

Kenyataan:
Artikel ini dikembalikan pada:lxlinux.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam