我最近正在学习linux网络驱动程序,我想知道如果我的主板上有很多相同类型的网卡,内核如何驱动它们呢?内核是否需要多次加载相同的驱动程序?我认为这是不可能的,insmod不会这样做,所以如何让所有同类卡同时工作?
问候
答案 0 :(得分:10)
每张卡的状态(I / O地址,IRQ,......)存储在一个特定于驱动程序的结构中,该结构(直接或间接)传递给驱动程序的每个入口点,这样可以区分卡片。这样,相同的代码可以控制不同的卡(这意味着是的,内核只保留驱动程序模块的一个实例,无论它控制的设备数量如何)。
例如,看看drivers/video/backlight/platform_lcd.c
,这是一个非常简单的LCD电源驱动程序。它包含一个名为platform_lcd
的结构,该结构对该文件是专用的,并存储LCD的状态(它是否被供电,以及它是否被暂停)。此结构的一个实例在驱动程序的probe
函数中通过kzalloc
分配 - 也就是说,每个LCD设备一个 - 并使用platform_set_drvdata
存储到代表LCD的平台设备中。然后,在所有其他驱动程序函数的开头提取已为此设备分配的实例,以便它知道它正在处理的实例:
struct platform_lcd *plcd = to_our_lcd(lcd);
to_our_lcd
扩展为lcd_get_data
,如果您查看dev_get_drvdata
,它会扩展为include/linux/lcd.h
(platform_set_drvdata的对应物)。然后,该函数可以知道已调用设备的状态。
这是一个非常简单的示例,platform_lcd
驱动程序不直接控制任何设备(这被推迟到平台数据中的函数指针),但添加了特定于硬件的参数(IRQ,I / O)基础等等)你得到了Linux中99%的驱动程序的工作原理。
答案 1 :(得分:4)
驱动程序代码只加载一次,但它为每张卡分配一个单独的上下文结构。通常,您会看到struct pci_driver
带有.probe
函数指针。 PCI支持代码为每个卡调用一次探测函数,并调用alloc_etherdev
为所需的私有上下文分配一个带空间的网络接口。