Linux kernel 仅卸载特定设备的内核模块(最好从另一个内核模块的代码中卸载)

Linux kernel 仅卸载特定设备的内核模块(最好从另一个内核模块的代码中卸载),linux-kernel,device,Linux Kernel,Device,我正在从事一个项目,其中我有一个管理系统,可以通过PCI Express将PCIe硬件设备导出到其他系统。我有一个工作的管理内核模块,但需要找到一种方法来确保我导出的设备没有在管理系统上为其加载驱动程序。如果没有这一点,设备将以冲突告终,因为同一个驱动程序将从两个不同的系统访问它&显然会导致问题 例如,假设我在Manager上安装了一个双端口Intel 100MBps NIC设备,该设备将在系统中显示2个PCIe端点(例如Fn 0和1)。两台设备都将加载Intel module e1000。如果

我正在从事一个项目,其中我有一个管理系统,可以通过PCI Express将PCIe硬件设备导出到其他系统。我有一个工作的管理内核模块,但需要找到一种方法来确保我导出的设备没有在管理系统上为其加载驱动程序。如果没有这一点,设备将以冲突告终,因为同一个驱动程序将从两个不同的系统访问它&显然会导致问题

例如,假设我在Manager上安装了一个双端口Intel 100MBps NIC设备,该设备将在系统中显示2个PCIe端点(例如Fn 0和1)。两台设备都将加载Intel module e1000。如果我想将该设备的端口2导出到另一个系统,我想将其与e1000模块“分离”

有没有人知道一种干净的方法可以做到这一点,而无需对内核进行黑客攻击或调整e1000的驱动程序的探测功能?我不能简单地做一个rmmod,因为这将同时删除两个NIC设备的模块。我希望我未导出的NIC在e1000驱动程序仍为其加载的情况下在管理系统中保持功能


基本上,rmmod会这样做,但会删除驱动程序所探测和拥有的所有设备的驱动程序。有没有办法告诉Linux“只卸载这个特定设备的模块”?在Windows上,我想这相当于右键单击设备管理器中的设备并选择“禁用”。

Linux驱动程序模型中负责设备/驱动程序配对的机制称为“总线”(通常通过/sys/bus中的条目控制)。问题是,您的设备所连接的特定总线驱动程序必须支持此类操作(在一般情况下,支持此功能绝非小事)

特别是对于PCI,如果启用了“PCI热插拔”,则可以通过将数字写入/sys/bus/PCI中相应的“热插拔”条目将设备从PCI总线上启动(也可以通过触发总线重新扫描将它们重新连接)。问题将在稍后开始,因为您必须以某种方式说服Linux设备子系统更喜欢您的驱动程序,而不是已经注册了相关设备id的驱动程序


通常注册的驱动程序会被添加到某种列表中,然后逐个进行测试,以查看其中一个是否在其“*\u device\u id”表中列出新的或重新启用的设备。如果PCI子系统倾向于按“首次注册,首次尝试”的顺序尝试驱动程序,则您必须对其进行破解以实现您的目标。

要解除PCI驱动程序与设备的绑定,请使用sysfs中驱动程序的
解除绑定
文件

文档/ABI/testing/sysfs-bus-pci

/sys/bus/pci/drivers/.../unbind Description: Writing a device location to this file will cause the driver to attempt to unbind from the device found at this location. This may be useful when overriding default bindings. The format for the location is: DDDD:BB:DD.F. That is Domain:Bus:Device.Function and is the same as found in /sys/bus/pci/devices/. For example: # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind /sys/bus/pci/drivers/../unbind 说明: 将设备位置写入此文件将导致 驱动程序尝试从位于的设备解除绑定 这个位置。这在覆盖默认值时可能很有用 绑定。位置的格式为:DDDD:BB:DD.F。 这是Domain:Bus:Device.Function,与 可在/sys/bus/pci/devices/中找到。例如: #echo 0000:00:19.0>/sys/bus/pci/drivers/foo/unbind
您可以通过重置相应设备的启用值来禁用特定pci设备

例如:


您可以通过写入以下方法禁用设备的驱动程序:

  • 使用
    sudo-i
    或在任何命令写入
    sudo
    之前以root用户身份操作。并遵循以下过程:
  • 转到
    /sys/bus/pci/
    文件夹
  • 发出命令
    echo-n 0000:03:00.1>解除绑定
  • 其中
    0000:03:00.1
    是要检测驱动程序的设备
  • 阅读链接,了解pci总线系统功能
echo 0 > /sys/bus/pci/devices/0000:00:1a.2/enable