制作initramfs的过程中需要为系统搭载的设备匹配驱动,linux下搜索驱动的方法众多,不同类型的设备可能会有不同的搜索方法,很难找到一种统一的方法。我摸索了很久,试图用/sys文件系统和udevadm来匹配各类设备对应的驱动。

windows会将设备分门别类的存放:比如将USB网卡/PCI网卡归为网卡类;移动硬盘/Scsi硬盘归入存储设备类。同样的归类方式也被linux所应用,linux将设备类存放在/sys/class下

eugen@ubuntu:/sys/class$ ls
ata_device  dma          input     power_supply  scsi_disk      vc
ata_link    dmi          leds      ppdev         scsi_generic   virtio-ports
ata_port    drm          mdio_bus  ppp           scsi_host      vtconsole
backlight   extcon       mem       printer       sound          watchdog
bdi         firmware     misc      pwm           spi_host
block       graphics     mmc_host  regulator     spi_master
bluetooth   hidraw       net       rfkill        spi_transport
bsg         hwmon        pci_bus   rtc           thermal
devfreq     i2c-adapter  powercap  scsi_device   tty

linux系统/sys/class下也有网卡类目录net/和块设备类block/等。进入net/目录可以看到比较清晰的各种设备:

eugen@ubuntu:/sys/class/net$ ls
eth0  lo

再进入eth0目录,可以看到这里的文件多数是/sys/device /sys/driver目录下的软连接

eugen@ubuntu:/sys/class/net$ cd eth0
eugen@ubuntu:/sys/class/net/eth0$ ll
total 0
drwxr-xr-x 5 root root    0 Jul 18  2016 ./
drwxr-xr-x 3 root root    0 Jul 18  2016 ../
-r--r--r-- 1 root root 4096 Jul 18  2016 addr_assign_type
...
lrwxrwxrwx 1 root root    0 Jul 18  2016 device -> ../../../0000:02:01.0/
-r--r--r-- 1 root root 4096 Jul 18  2016 dev_id
...
drwxr-xr-x 2 root root    0 Feb  8 07:47 statistics/
lrwxrwxrwx 1 root root    0 Jul 18  2016 subsystem -> ../../../../../../class/net/
-rw-r--r-- 1 root root 4096 Feb  8 07:47 tx_queue_len
-r--r--r-- 1 root root 4096 Jul 18  2016 type
-rw-r--r-- 1 root root 4096 Jul 18  2016 uevent

当然,也可以直接到/sys/device目录下通过总线关系来查找设备,不过这实在是太麻烦了:

eugen@ubuntu:/sys/class/net/eth0$ ls /sys/devices/pci0000\:00/
0000:00:00.0  0000:00:15.0  0000:00:16.1  0000:00:17.2  0000:00:18.3
0000:00:01.0  0000:00:15.1  0000:00:16.2  0000:00:17.3  0000:00:18.4
0000:00:07.0  0000:00:15.2  0000:00:16.3  0000:00:17.4  0000:00:18.5
0000:00:07.1  0000:00:15.3  0000:00:16.4  0000:00:17.5  0000:00:18.6
0000:00:07.3  0000:00:15.4  0000:00:16.5  0000:00:17.6  0000:00:18.7
0000:00:07.7  0000:00:15.5  0000:00:16.6  0000:00:17.7  firmware_node
0000:00:0f.0  0000:00:15.6  0000:00:16.7  0000:00:18.0  pci_bus
0000:00:10.0  0000:00:15.7  0000:00:17.0  0000:00:18.1  power
0000:00:11.0  0000:00:16.0  0000:00:17.1  0000:00:18.2  uevent

面对这么多数字编号的文件,鬼晓得哪个是我想要搜索的网卡设备...

回到我们的设备类目录中,现在我们知道系统上搭载了哪些设备后,就可以准备搜索这个设备对应的驱动程序了,这就要借助udevadm工具了。

eugen@ubuntu:/sys/class/net/eth0$ udevadm info -a -p /sys/class/net/eth0 # -p:要查询设备在/sys下的路径,-a:设备uevent属性,info:udevadm查询功能 looking at device '/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0':KERNEL=="eth0"SUBSYSTEM=="net"DRIVER==""ATTR{mtu}=="1500"ATTR{type}=="1"ATTR{netdev_group}=="0"ATTR{flags}=="0x1003"ATTR{dormant}=="0"ATTR{addr_assign_type}=="0"ATTR{dev_id}=="0x0"ATTR{iflink}=="2"ATTR{addr_len}=="6"ATTR{address}=="00:0c:29:72:87:d8"ATTR{operstate}=="up"ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"ATTR{tx_queue_len}=="1000"ATTR{ifalias}==""ATTR{ifindex}=="2"ATTR{link_mode}=="0"ATTR{carrier}=="1"looking at parent device '/devices/pci0000:00/0000:00:11.0/0000:02:01.0':KERNELS=="0000:02:01.0"SUBSYSTEMS=="pci"DRIVERS=="pcnet32" #<----------设备相关的驱动模块ATTRS{irq}=="19"ATTRS{subsystem_vendor}=="0x1022"ATTRS{broken_parity_status}=="0"ATTRS{class}=="0x020000"ATTRS{label}=="Ethernet0"ATTRS{enabled}=="1"ATTRS{consistent_dma_mask_bits}=="32"ATTRS{dma_mask_bits}=="32"ATTRS{local_cpus}=="ff"ATTRS{device}=="0x2000"ATTRS{msi_bus}==""ATTRS{local_cpulist}=="0-7"ATTRS{vendor}=="0x1022"ATTRS{acpi_index}=="16777736"ATTRS{subsystem_device}=="0x2000"ATTRS{d3cold_allowed}=="0"looking at parent device '/devices/pci0000:00/0000:00:11.0':KERNELS=="0000:00:11.0"SUBSYSTEMS=="pci"DRIVERS==""ATTRS{irq}=="0"ATTRS{subsystem_vendor}=="0x15ad"ATTRS{broken_parity_status}=="0"ATTRS{class}=="0x060401"ATTRS{enabled}=="1"ATTRS{consistent_dma_mask_bits}=="32"ATTRS{dma_mask_bits}=="32"ATTRS{local_cpus}=="ff"ATTRS{device}=="0x0790"ATTRS{msi_bus}=="1"ATTRS{local_cpulist}=="0-7"ATTRS{vendor}=="0x15ad"ATTRS{subsystem_device}=="0x0790"ATTRS{d3cold_allowed}=="0"looking at parent device '/devices/pci0000:00':KERNELS=="pci0000:00"SUBSYSTEMS==""DRIVERS==""

在udevadm是以设备树的形式由叶节点向根节点输出,行中最前面的是设备,往后是设备所挂载的插槽或者总线,以"looking at"分割每个节点。如果节点中"DRIVERS="之后不为空,则其中的内容就是与设备相匹配的驱动。比如这里的eth0设备,它的驱动程序是pcnet32。
    如同windows以设备的venderID/deviceID来匹配驱动(驱动也会有个兼容列表,列举了该驱动可以兼容的设备),linux也是通过这样的方式匹配设备和驱动。上面ls的结果中我们看到了eth0匹配到pcnet32驱动,我们来看下这个设备的vid/pid信息,udevadm也输出了设备的vid/pid(subsystem-vid/subsystem-pid如果有的话):

looking at parent device '/devices/pci0000:00/0000:00:11.0/0000:02:01.0':KERNELS=="0000:02:01.0"SUBSYSTEMS=="pci"DRIVERS=="pcnet32"...ATTRS{subsystem_vendor}=="0x1022" #subsystem_vid...ATTRS{device}=="0x2000" #deviceId...ATTRS{vendor}=="0x1022" #vendorIrATTRS{subsystem_device}=="0x2000" #subsystem_device

那pcnet32这个驱动兼容列表里是否包含这个设备呢?这需要通过modinfo来查看,这个工具除了显示模块依赖信息,还包含驱动兼容列表v****代表厂商id d****代表设备id sv***代表子厂商id sd***代表子设备id:

eugen@ubuntu:/sys/class/net/eth0$ modinfo pcnet32
filename:       /lib/modules/3.13.0-32-generic/kernel/drivers/net/ethernet/amd/pcnet32.ko
license:        GPL
description:    Driver for PCnet32 and PCnetPCI based ethercards
author:         Thomas Bogendoerfer
srcversion:     C4943E68861BEE404D99565
alias:          pci:v00001023d00002000sv*sd*bc02sc00i*
alias:          pci:v00001022d00002000sv*sd*bc*sc*i* #<------这个alias完全匹配我们的设备,因此为我们的驱动加载了pcnet32模块
alias:          pci:v00001022d00002001sv*sd*bc*sc*i*
depends:        mii
intree:         Y
vermagic:       3.13.0-32-generic SMP mod_unload modversions 686
signer:         Magrathea: Glacier signing key
sig_key:        A7:FC:65:90:FC:4A:8D:85:9A:AE:BD:A2:CA:5D:D0:47:16:24:4F:A0
sig_hashalgo:   sha512
parm:           debug:pcnet32 debug level (int)
parm:           max_interrupt_work:pcnet32 maximum events handled per interrupt (int)
parm:           rx_copybreak:pcnet32 copy breakpoint for copy-only-tiny-frames (int)
parm:           tx_start_pt:pcnet32 transmit start point (0-3) (int)
parm:           pcnet32vlb:pcnet32 Vesa local bus (VLB) support (0/1) (int)
parm:           options:pcnet32 initial option setting(s) (0-15) (array of int)
parm:           full_duplex:pcnet32 full duplex setting(s) (1) (array of int)
parm:           homepna:pcnet32 mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet (array of int)

最后,在看看我虚拟机上sda设备的驱动:

ugen@ubuntu:/sys/class/block$ udevadm info -a -p /sys/class/block/sdalooking at device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda':KERNEL=="sda"SUBSYSTEM=="block"DRIVER==""ATTR{ro}=="0"ATTR{size}=="41943040"ATTR{stat}=="   29068    11872  1077742  1948848     3000     6461   247072  1304440        0   198688  3252304"ATTR{range}=="16"ATTR{discard_alignment}=="0"ATTR{events}==""ATTR{ext_range}=="256"ATTR{events_poll_msecs}=="-1"ATTR{alignment_offset}=="0"ATTR{inflight}=="       0        0"ATTR{removable}=="0"ATTR{capability}=="50"ATTR{events_async}==""looking at parent device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0':KERNELS=="32:0:0:0"SUBSYSTEMS=="scsi"DRIVERS=="sd" ATTRS{rev}=="1.0 "ATTRS{type}=="0"ATTRS{scsi_level}=="3"ATTRS{model}=="VMware Virtual S"ATTRS{state}=="running"ATTRS{queue_type}=="simple"ATTRS{iodone_cnt}=="0x7d82"ATTRS{iorequest_cnt}=="0x7d82"ATTRS{queue_ramp_up_period}=="120000"ATTRS{device_busy}=="0"ATTRS{evt_capacity_change_reported}=="0"ATTRS{timeout}=="180"ATTRS{evt_media_change}=="0"ATTRS{ioerr_cnt}=="0x9"ATTRS{queue_depth}=="32"ATTRS{vendor}=="VMware, "ATTRS{evt_soft_threshold_reached}=="0"ATTRS{device_blocked}=="0"ATTRS{evt_mode_parameter_change_reported}=="0"ATTRS{evt_lun_change_reported}=="0"ATTRS{evt_inquiry_change_reported}=="0"ATTRS{iocounterbits}=="32"ATTRS{eh_timeout}=="10"looking at parent device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0':KERNELS=="target32:0:0"SUBSYSTEMS=="scsi"DRIVERS==""looking at parent device '/devices/pci0000:00/0000:00:10.0/host32':KERNELS=="host32"SUBSYSTEMS=="scsi"DRIVERS==""looking at parent device '/devices/pci0000:00/0000:00:10.0':KERNELS=="0000:00:10.0"SUBSYSTEMS=="pci"DRIVERS=="mptspi" #磁盘设备的驱动程序是mptspiATTRS{irq}=="17"ATTRS{subsystem_vendor}=="0x15ad"ATTRS{broken_parity_status}=="0"ATTRS{class}=="0x010000"ATTRS{enabled}=="1"ATTRS{consistent_dma_mask_bits}=="32"ATTRS{dma_mask_bits}=="32"ATTRS{local_cpus}=="ff"ATTRS{config}==""ATTRS{device}=="0x0030" #deviceIDATTRS{msi_bus}==""ATTRS{local_cpulist}=="0-7"ATTRS{vendor}=="0x1000" #vidATTRS{subsystem_device}=="0x1976"ATTRS{d3cold_allowed}=="0"looking at parent device '/devices/pci0000:00':KERNELS=="pci0000:00"SUBSYSTEMS==""DRIVERS==""

看看mptspi的兼容列表:

eugen@ubuntu:/sys/class/block$ modinfo mptspi
filename:       /lib/modules/3.13.0-32-generic/kernel/drivers/message/fusion/mptspi.ko
version:        3.04.20
license:        GPL
description:    Fusion MPT SPI Host driver
author:         LSI Corporation
srcversion:     C704B01EA98284063D3E1F6
alias:          pci:v00001000d00000040sv*sd*bc*sc*i*
alias:          pci:v0000117Cd00000030sv*sd*bc*sc*i*
alias:          pci:v00001000d00000030sv*sd*bc*sc*i* #这个alisa可以匹配我的磁盘
depends:        mptscsih,mptbase
intree:         Y
vermagic:       3.13.0-32-generic SMP mod_unload modversions 686
signer:         Magrathea: Glacier signing key
sig_key:        A7:FC:65:90:FC:4A:8D:85:9A:AE:BD:A2:CA:5D:D0:47:16:24:4F:A0
sig_hashalgo:   sha512
parm:           mpt_saf_te: Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0) (int)

有了这些信息后,就可以在制作initramfs时包含必要的驱动以减小initramfs的空间。

附注:

有时候/sys/class下可能会遇到模棱两可的设备,这时,可以到/sys/bus目录下最终定位设备~

使用udevadm(modinfo)查找linux下设备对应的驱动相关推荐

  1. Linux下设备树中常用的of操作函数举例

    文章目录 前言 一.在设备树中添加自定义节点 二.用到的of函数简介 1.用到的结构体 2.各of函数介绍 1>.of_find_node_by_path 2>.of_find_prope ...

  2. Linux下的USB总线驱动 mouse

    Linux下的USB总线驱动(03)--USB鼠标驱动 usbmouse.c USB鼠标驱动 usbmouse.c 原文链接:http://www.linuxidc.com/Linux/2012-12 ...

  3. 南京邮电大学嵌入式系统开发实验5:嵌入式Linux下LED报警灯驱动设计及编程

    实验5  嵌入式Linux下LED报警灯驱动设计及编程 一.实验目的 理解驱动本质,掌握嵌入式Linux系统下驱动开发相关知识,包括端口寄存器访问.接口函数编写.和文件系统挂接.注册及相关应用编程等知 ...

  4. *Linux下的USB总线驱动 u盘驱动分析*

    Linux下的USB总线驱动(三) u盘驱动分析 版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 https://www.xuebuyuan.com/13 ...

  5. 如何编写Linux 下的 USB 键盘驱动

     如何编写Linux 下的 USB 键盘驱动 1. 指定 USB 键盘驱动所需的头文件: #include <linux/kernel.h>/*内核头文件,含有内核一些常用函数的原型定 ...

  6. Linux下编写ENC28J60网卡驱动,完善网络设备框架

    一.框架模型 linux下设备驱动都有一套标准的结构,字符设备,块设备,网络设备都是自己的一套框架.编写驱动只需要把内核的框架搞清楚,然后照着结构填入参数,注册进内核,在应用层就可以按照标准的形式调用 ...

  7. usb hub 要驱动 linux,Linux下的USB HUB驱动

    Linux下的USB HUB驱动 [日期:2012-07-29] 来源:Linux社区 作者:zhengmeifu [字体:大 中 小] 五:hub接口驱动分析 5.1:接口驱动架构 是时候来分析接口 ...

  8. linux usb root hub,Linux下的USB HUB驱动

    Linux下的USB HUB驱动 [日期:2012-07-29] 来源:Linux社区 作者:zhengmeifu [字体:大 中 小] 接下来,就要对设备进行配置了,首先,将设备唤醒.回忆一下我们在 ...

  9. 在Fedora 16 linux下安装USB无线网卡驱动88x2bu

    在Fedora 16 linux下安装USB无线网卡驱动88x2bu USB无线网卡翼联EP-AC1610兼容linux系统 我之前已经买了一个USB无线网卡是水星mw150us,但是没有linux驱 ...

  10. linux 安装水星无线网卡驱动,Linux下安装RTL8188CE网卡驱动(Mercury MW150U)

    先说明下我的系统: kernel: 3.0.0-32-generic 今天买了个无线网卡Mercury 150Mbps MW150U系列,我发现在我的笔记本的Ubuntu 12.10下不用安装驱动就能 ...

最新文章

  1. python中print又可将数据写入文件_Python 通过print_lol将数据保存到文件中
  2. Rstudio查看关联的R
  3. 图的数组(邻接矩阵)存储结构
  4. 【Qt笔记】对象模型
  5. Hadoop伪集群环境搭建
  6. NLP:基于nltk和jieba库对文本实现提取文本摘要(两种方法实现:top_n_summary和mean_scored_summary)
  7. 接入上文,StarWind V2V Image Converter:虚拟机镜像转换工具,如何使用转化之后的 VMware VMDK 文件
  8. 流感传染(信息学奥赛一本通-T1191)
  9. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的田径运动会管理系统
  11. arraylist 初始化_ArrayList - 遍历ArrayList的三种方法
  12. 系统集成项目管理工程师02《项目立项管理》
  13. opencv 查找白色图片的一个黑点
  14. 51单片机对直流电机的控制(使用proteus仿真)
  15. Java期末复习速成(一)
  16. react创建ts项目
  17. 冰刃(icesword) V1.22 Beta1┊查探系统中幕后黑手-木马后门┊英文绿色免费版
  18. ACPC2017游记
  19. 计算机视觉领域顶级会议和顶级期刊
  20. 电商领域用户的留存分析

热门文章

  1. 学习英语是一辈子的事
  2. php 项目迁移注意事项,网站数据迁移规范及注意事项
  3. drf:RBAC-基于角色的访问控制、Django的内置RBAC(六表)、Xadmin的使用
  4. 解决SpringBoot中jar包部署没有主清单属性的问题
  5. 《硅谷》第三季第一集神秘代码
  6. 第3章 Java 主方法中的循环结构
  7. 实时系统vxWorks - 在线调试
  8. 南北方饮食文化的多态
  9. iPhone 应用开发的5个贴士
  10. Python实现带头结点的单向链表