Board logo

标题: 如何在LINUX下实现硬件的自动检测-1 [打印本页]

作者: look_w    时间: 2018-4-15 19:48     标题: 如何在LINUX下实现硬件的自动检测-1

设备检测的一般介绍一般而言,在Linux下进行设备自动检测是根据设备的总线类型进行的。现在的微机系统上最常见的总线类型有PCI、SERIAL、USB、PCMCIA、PARPORT、ISA、SCSI等。对于检测过程,一般不是通过c语言的库函数直接对设备进行访问,并读取设备的信息,而是通过内核的/proc文件系统进行。这种检测方式,充分利用了内核中关于硬件的多种检测函数,具有高效、稳定的特点,并且在内核版本升级之后,使程序的变化也为最小。对于大多数现在流行的系统硬件,在插入适当的模块之后,内核会在/proc文件系统中生成相应的描述文件。检测过程就是读取这样的文件,并将其信息进行相应的处理,从中提取出设备标识、设备描述、设备工作状态等信息。
由于涉及到对/proc文件系统的访问,并可能在检测过程开始时插入需要的设备模块,所以需要用户以root用户方式执行下面所说的操作。
在检测过程结束的时候,用户一般能够得到设备的唯一标识(制造商标识和设备标识)和设备的当前的状态信息。这时就需要一个设备数据库,这个数据库将设备的唯一标识和对应的设备驱动程序对应起来,然后由此生成/etc/modules.conf中的对应表项及其他配置脚本,完成整个的硬件配置过程。
PCI设备的自动检测2.1 PCI设备简介对于每个pci设备都由一个总线号、一个设备号和一个功能号确定。PCI设备可以访问三类地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。前两者可由PCI总线上的所有设备共享。PCI的配置空间由256个字节构成,其布局是标准化的。下表显示的是配置空间中前64字节的每个配置寄存器的分布情况:
Vendor IDDevice IDCommand RegStatus RegRevision IDClass CodeCache LineLatency TimerHeader TypeBISTBase Address 0Base Address 1Base Address 2Base Address 3Base Address 4Base Address 5CardBus CIS pointerSubsystem Vendor IDSubsystem Device IDExpansion ROM Base AddReserved(PCI Capability List)ReservedIRQ LineIRQ PinMin_GntMax_Latclass code
设备的类型标识,类寄存器是16位的值。它的高八位确定基类,如SCSI设备的分类码位0x0100。Linux系统的定义见<linux/pci.h>中的声明。现在摘录如下:      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#define PCI_CLASS_NOT_DEFINED           0x0000
#define PCI_CLASS_NOT_DEFINED_VGA       0x0001
#define PCI_BASE_CLASS_STORAGE          0x01
#define PCI_CLASS_STORAGE_SCSI          0x0100
#define PCI_CLASS_STORAGE_IDE           0x0101
#define PCI_CLASS_STORAGE_FLOPPY        0x0102
#define PCI_CLASS_STORAGE_IPI           0x0103
#define PCI_CLASS_STORAGE_RAID          0x0104
#define PCI_CLASS_STORAGE_OTHER         0x0180
#define PCI_BASE_CLASS_NETWORK          0x02
#define PCI_CLASS_NETWORK_ETHERNET      0x0200
#define PCI_CLASS_NETWORK_TOKEN_RING        0x0201
#define PCI_CLASS_NETWORK_FDDI          0x0202
#define PCI_CLASS_NETWORK_ATM           0x0203
#define PCI_CLASS_NETWORK_OTHER         0x0280
#define PCI_BASE_CLASS_DISPLAY          0x03
#define PCI_CLASS_DISPLAY_VGA           0x0300
#define PCI_CLASS_DISPLAY_XGA           0x0301
#define PCI_CLASS_DISPLAY_OTHER         0x0380
#define PCI_BASE_CLASS_MULTIMEDIA       0x04
#define PCI_CLASS_MULTIMEDIA_VIDEO      0x0400
#define PCI_CLASS_MULTIMEDIA_AUDIO      0x0401
#define PCI_CLASS_MULTIMEDIA_OTHER      0x0480
#define PCI_BASE_CLASS_MEMORY           0x05
#define  PCI_CLASS_MEMORY_RAM           0x0500
#define  PCI_CLASS_MEMORY_FLASH         0x0501
#define  PCI_CLASS_MEMORY_OTHER         0x0580
#define PCI_BASE_CLASS_BRIDGE           0x06
#define  PCI_CLASS_BRIDGE_HOST          0x0600
#define  PCI_CLASS_BRIDGE_ISA           0x0601
#define  PCI_CLASS_BRIDGE_EISA          0x0602
#define  PCI_CLASS_BRIDGE_MC            0x0603
#define  PCI_CLASS_BRIDGE_PCI           0x0604
#define  PCI_CLASS_BRIDGE_PCMCIA        0x0605
#define  PCI_CLASS_BRIDGE_NUBUS         0x0606
#define  PCI_CLASS_BRIDGE_CARDBUS       0x0607
#define  PCI_CLASS_BRIDGE_OTHER         0x0680
#define PCI_BASE_CLASS_COMMUNICATION        0x07
#define PCI_CLASS_COMMUNICATION_SERIAL      0x0700
#define PCI_CLASS_COMMUNICATION_PARALLEL    0x0701
#define PCI_CLASS_COMMUNICATION_OTHER       0x0780
#define PCI_BASE_CLASS_SYSTEM           0x08
#define PCI_CLASS_SYSTEM_PIC            0x0800
#define PCI_CLASS_SYSTEM_DMA            0x0801
#define PCI_CLASS_SYSTEM_TIMER          0x0802
#define PCI_CLASS_SYSTEM_RTC            0x0803
#define PCI_CLASS_SYSTEM_OTHER          0x0880
#define PCI_BASE_CLASS_INPUT            0x09
#define PCI_CLASS_INPUT_KEYBOARD        0x0900
#define PCI_CLASS_INPUT_PEN         0x0901
#define PCI_CLASS_INPUT_MOUSE           0x0902
#define PCI_CLASS_INPUT_OTHER           0x0980
#define PCI_BASE_CLASS_DOCKING          0x0a
#define PCI_CLASS_DOCKING_GENERIC       0x0a00
#define PCI_CLASS_DOCKING_OTHER         0x0a01
#define PCI_BASE_CLASS_PROCESSOR        0x0b
#define PCI_CLASS_PROCESSOR_386         0x0b00
#define PCI_CLASS_PROCESSOR_486         0x0b01
#define PCI_CLASS_PROCESSOR_PENTIUM     0x0b02
#define PCI_CLASS_PROCESSOR_ALPHA       0x0b10
#define PCI_CLASS_PROCESSOR_POWERPC     0x0b20
#define PCI_CLASS_PROCESSOR_CO          0x0b40
#define PCI_BASE_CLASS_SERIAL           0x0c
#define PCI_CLASS_SERIAL_FIREWIRE       0x0c00
#define PCI_CLASS_SERIAL_ACCESS         0x0c01
#define PCI_CLASS_SERIAL_SSA            0x0c02
#define PCI_CLASS_SERIAL_USB            0x0c03
#define PCI_CLASS_SERIAL_FIBER          0x0c04
#define PCI_CLASS_SERIAL_SMBUS          0x0c05
#define PCI_BASE_CLASS_INTELLIGENT      0x0e
#define PCI_CLASS_INTELLIGENT_I2O       0x0e00
#define PCI_CLASS_HOT_SWAP_CONTROLLER       0xff00
#define PCI_CLASS_OTHERS            0xff




Base Address 0- Base Address 5
表示此卡占用的内存范围。      
IRQ Line
指定的设备所使用的中断号,它在系统启动时由固件复制。      
IRQ Pin
PCI卡有4个物理引脚,用于把中断从卡上发送到PCI总线上。为0表示设备不支持中断,非0表示使用哪一个终端引脚。此信息可让中断处理子系统处理来自该设备的中断。      
关于pci设备的其他信息,您可以参考PCI Local BusSpecification。
2.2 Linux下PCI设备的检测过程一个pci设备可映射到最多六个地址区段。每个区段由内存或I/O位置组成。区段的大小和当前位置由配置寄存器报告。
检测pci设备先要打开文件/proc/bus/pci/devices,例如存在下列数据:
1
003980867111    0000000000000000000000000000000000000f0010000000000000000




上面的数据表示一个pci设备,对于第一个数字0039(十六进制表示),高八位表示总线号(bus),对于低三位表示功能号(function),剩余的五位表示设备号(device)。也就是说,0039表示,总线0,设备号为7,功能号为1。由此,内核生成设备对应的文件/proc/bus/pci/bus/device.function。此文件为256个字节,对应读出的设备配置信息,第十字节开始的双字节表示设备的类型。第二个数字80867111表示,设备的vendorid为8086,deviceid为7111。通过查询设备配置数据库可知设备标识80867111表示Intel Corporation|82371AB PIIX4 IDE控制器。第三个数字表示占用的irq。
用户可以通过察看/proc/pci文件,可以获得系统连接的pci设备的基本信息描述,或者用户也可以使用命令lspci(需要安装包pciutils)来察看PCI设备较为详细的描述信息。但是为了使内核显示上述信息,必须要在编译内核时加入PCI设备名数据库,这会使内核增大约80KB。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0