linux设备驱动程序.docx
- 文档编号:17850272
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:21
- 大小:38.28KB
linux设备驱动程序.docx
《linux设备驱动程序.docx》由会员分享,可在线阅读,更多相关《linux设备驱动程序.docx(21页珍藏版)》请在冰点文库上搜索。
linux设备驱动程序
linux设备驱动程序
系统和BIOS概述
现代的个人计算机(PC)系统都包括一个用于进行计算的中央处理单元(CPU)以及用来存储处理器所使用的数据的一些内存。
为了使用此设备,我们需要连接外围设备,比如键盘、鼠标、显示器、硬盘、CD或DVD驱动器、打印机、扫描仪和网卡,这就使我们能够输入、存储、打印、显示和传输数据。
在刚刚描述的计算机中,处理器所使用的内存称为随机访问存储器(RandomAccessMemory,RAM)。
在典型的PC中,此内存是易失的(volatile),也就是说,它需要有电源才能保存数据。
关闭PC,内存就会被清空。
从另一个角度来说,当我们关闭一台PC后,它就只是一堆硬件组件,什么也做不了,直到它被重构(reprogrammed)。
当启动机器时会发生重构;这个过程称作引导(bootstrapping或booting)计算机。
引导过程和BIOS
引导的过程涉及到从外部存储设备(比如软盘、CD、DVD、硬盘或者存储钥匙(memorykey))中加载操作系统。
执行这一初始加载的程序固化存储在计算机中,称为基本输入输出系统(BasicInputOutputSystem,BIOS)。
BIOS存储在非易失性的(non-volatile)存储器中,有时也称作只读存储器(ReadOnlyMemory,ROM)。
在早期的PC中,ROM芯片通常焊接或者套接在计算机的主板上(或者母板)。
更新BIOS意味着要更换ROM芯片。
后来,使用了ElectricallyErasableProgrammableReadOnlyMemories(EEPROMs)。
EEPROM支持使用磁盘在运行中进行更新,而不需要专门的工具。
现今您应该会更经常接触到的一种称为闪存(Flash)存储器的非易失性存储器,数码相机和存储钥匙也使用了它。
闪存存储器也支持在运行时更新BIOS。
除了控制PC的初始引导之外,现今的BIOS程序通常还允许用户设置或者检查系统中的一些配置选项。
包括检查已经安装的部件,比如RAM、硬盘驱动器、光驱(opticaldrive)、键盘、鼠标,以及可能的板载显示部件、声音部件和网络连接。
用户可以启用或者禁用某些部件。
例如,为了使用安装的声卡,板载的声音部件可能被禁用。
用户还可以选择考虑使用哪些设备来引导系统,以及是否使用口令保护系统。
要访问BIOS设置屏幕,通常需要有一个连接到系统的键盘。
当系统加电启动时,会执行PowerOnSelfTest或者POST。
在某些系统中,会简短地提示您按下一个特定的键来进入设置,否则就会进行正常引导。
在其他系统上,需要知道在调用正常引导过程之前按哪个键,因为可能没有提示,或者在先前对设置选项的定制删除了提示。
在某些系统中,除了进入BIOS设置以外,可能还会有其他选择,
以上插图是可能会看到的内容示例,不过,各个BIOS设置屏幕差异很大,所以如果看到了不同的屏幕不要感到惊讶。
告诉我们,闪存EEPROM(或者系统BIOS)
总线、端口、IRQ和DMA。
PCI和ISA总线
外围设备(包括那些可能构建在系统板中的)通过总线与CPU通信。
当前最常见的总线类型是PeripheralComponentInterconnect(PCI)总线,它几乎已经完全取代了更早的IndustryStandardArchitecture(ISA)总线。
1984年IBMPC-AT中首次使用它,之后ISA总线有时也称为AT总线。
在从ISA到PCI总线的过渡过程中,很多系统同时包含了这两类总线的插槽,以使得ISA或PCI外围设备都能够使用。
ISA总线支持8-位和16-位设备卡,而PCI总线支持32-位设备。
还有一些也应该了解的其他总线标准。
很多系统中包括一个AcceleratedGraphicsPort(AGP)插槽,这是一个基于PCI2.1总线规范的特殊插槽,但是为图形卡所需要的高带宽和快速响应进行了优化。
它正在慢慢被更新的PCIExpress(PCI-E)所取代,后者解决了先前PCI设计中的很多限制。
在本系列的最后一节中将深入了解Linux文件系统,不过,在此先介绍/proc文件系统。
这不是一个磁盘上的真实文件系统,而是一个“假的文件系统”,提供关于正在运行的系统的信息。
在这个文件系统中,文件/proc/pci包含了系统PCI总线上设备的信息。
曾经有一些关于废除这个特殊文件的讨论,因为lspci命令可以给出类似的信息。
运行cat/proc/pci命令,可以看到类似于清单1的输出。
清单1./proc/pci
PCIdevicesfound:
Bus0,device0,function0:
Hostbridge:
IntelCorp.82845G/GL[Brookdale-G]ChipsetHostBridge(rev1).Prefetchable32bitmemoryat0xd0000000[0xdfffffff].Bus0,device2,function0:
VGAcompatiblecontroller:
IntelCorp.82845G/GL[Brookdale-G]ChipsetIntegratedGraphicsDevice(rev1).IRQ11.Prefetchable32bitmemoryat0x88000000[0x8fffffff].Non-prefetchable32bitmemoryat0x80000000[0x8007ffff].Bus0,device29,function0:
USBController:
IntelCorp.82801DBUSB(Hub#1)(rev1).IRQ11.I/Oat0x1800[0x181f].Bus0,device29,function1:
USBController:
IntelCorp.82801DBUSB(Hub#2)(rev1).IRQ10.I/Oat0x1820[0x183f].Bus0,device29,function2:
USBController:
IntelCorp.82801DBUSB(Hub#3)(rev1).IRQ5.I/Oat0x1840[0x185f].Bus0,device29,function7:
USBController:
IntelCorp.82801DBUSB2(rev1).IRQ9.Non-prefetchable32bitmemoryat0xc0080000[0xc00803ff].Bus0,device30,function0:
PCIbridge:
IntelCorp.82801BA/CA/DB/EBPCIBridge(rev129).MasterCapable.Nobursts.MinGnt=4.Bus0,device31,function0:
ISAbridge:
IntelCorp.82801DBLPCInterfaceController(rev1).Bus0,device31,function1:
IDEinterface:
IntelCorp.82801DBUltraATAStorageController(rev1).IRQ5.I/Oat0x1860[0x186f].Non-prefetchable32bitmemoryat0x60000000[0x600003ff].Bus0,device31,function3:
SMBus:
IntelCorp.82801DB/DBMSMBusController(rev1).IRQ9.I/Oat0x1880[0x189f].Bus0,device31,function5:
Multimediaaudiocontroller:
IntelCorp.82801DBAC'97AudioController(rev1).IRQ9.I/Oat0x1c00[0x1cff].I/Oat0x18c0[0x18ff].Non-prefetchable32bitmemoryat0xc0080c00[0xc0080dff].Non-prefetchable32bitmemoryat0xc0080800[0xc00808ff].Bus2,device8,function0:
Ethernetcontroller:
IntelCorp.82801BDPRO/100VE(LOM)EthernetController(rev129).IRQ9.MasterCapable.Latency=66.MinGnt=8.MaxLat=56.Non-prefetchable32bitmemoryat0xc0100000[0xc0100fff].I/Oat0x2000[0x203f].
您可能希望对此输出与lspci命令的输出进行比较。
后者通常在root用户的路径中,但非-root用户可能需要给出完全的路径/sbin/lspci。
在自己的系统去进行尝试。
IO端口
当CPU需要与某个外围设备通信时,它要通过一个IO端口(有时只是简单的端口)。
当CPU需要向外围设备发送数据或者控制信息时,它向某个端口写入数据。
当设备为CPU准备好了数据或者状态,CPU从某个端口去读取数据或状态。
大部分设备都拥有不止一个与之相关联的端口,通常是2的若干次幂(指数较小),比如8、16或者32。
数据传输通常是每次一个或两个字节。
设备不能共享端口,所以,如果有ISA卡,那么必须确保每个设备都有其分配到了自己的端口。
以前,这需要通过设备卡上的开关或者跳线来实现。
一些晚期的ISA卡使用了一个名为PlugandPlay(PnP)的系统,本节稍后将讨论到。
PCI卡全都有PnP配置。
在/proc文件系统中,/proc/ioports文件告诉我们关于系统中可用IO端口的信息。
运行cat/proc/ioports命令可以看到类似清单2所示的输出。
清单2./proc/ioports
0000-001f:
dma10020-003f:
pic10040-005f:
timer0060-006f:
keyboard0070-007f:
rtc0080-008f:
dmapagereg00a0-00bf:
pic200c0-00df:
dma200f0-00ff:
fpu0170-0177:
ide101f0-01f7:
ide002f8-02ff:
serial(auto)0376-0376:
ide10378-037a:
parport003c0-03df:
vga+03f6-03f6:
ide003f8-03ff:
serial(auto)0cf8-0cff:
PCIconf11800-181f:
IntelCorp.82801DBUSB(Hub#1)1800-181f:
usb-uhci1820-183f:
IntelCorp.82801DBUSB(Hub#2)1820-183f:
usb-uhci1840-185f:
IntelCorp.82801DBUSB(Hub#3)1840-185f:
usb-uhci1860-186f:
IntelCorp.82801DBUltraATAStorageController1860-1867:
ide01868-186f:
ide11880-189f:
IntelCorp.82801DB/DBMSMBusController18c0-18ff:
IntelCorp.82801DBAC'97AudioController18c0-18ff:
IntelICH41c00-1cff:
IntelCorp.82801DBAC'97AudioController1c00-1cff:
IntelICH42000-203f:
IntelCorp.82801BDPRO/100VE(LOM)EthernetController2000-203f:
e100
端口编号是十六进制的(基数为16)。
肯定会发现有一些看起来很熟悉,比如键盘、计时器、并行端口(打印机)、串行端口(调制解调器)和显示器(vga+)。
将这些与清单3中给出了在PC中某些标准IO端口分配进行比较。
例如,要注意的是,在/proc/ioports中为第一个并行端口(parport0)分配的地址范围是从0378到037A,而标准中允许它(LPT!
)使用的是从378到37F。
清单3.标准I/O端口设置
1FO-1F8-HardDriveController,16-bitISA200-20F-GameControl210-GameI/O220-Soundcard278-27F-LPT22F8-2FF-COM2320-32F-HardDriveController,8-bitISA378-37F-LPT13B0-3BF-MonochromeGraphicsAdapter(MGA)3D0-3DF-ColourGraphicsAdapter(CGA)3F0-3F7-FloppyController3F8-3FF-COM1
中断
那么,CPU如何知道最后一次输出何时完成?
或者何时有数据在等待读取?
通常,在一个状态寄存器中可以获得此信息,通过读取与某设备想关联的一个(或多个)IO端口可以访问它。
在这种情况下会出现两个问题。
首先,CPU不得不花费时间来检查状态。
其次,如果设备持有来自某处的数据,比如连接的调制解调器,那些数据必须要及时被读取,否则就可能被下一个可用的数据字节所覆盖。
不浪费多余CPU周期,并确保数据能被及时读写,这两个问题是由中断(interrupt)的概念所解决的。
中断也称为中断请求(InterruptRequests)或IRQs。
当设备中发生CPU需要知道的某事件时,设备就会发出一个中断,CPU则临时停止正在做的其他工作,来处理那件事情。
根据上一节的经验,毫无疑问关于中断的信息也保存在/proc文件系统中,在/proc/interrupts中。
运行cat/proc/interrupts命令,可以看到类似于清单4的输出。
清单4./proc/interrupts
CPU00:
226300426XT-PICtimer1:
92913XT-PICkeyboard2:
0XT-PICcascade5:
0XT-PICusb-uhci8:
1XT-PICrtc9:
2641134XT-PICehci-hcd,eth0,IntelICH410:
0XT-PICusb-uhci11:
213632XT-PICusb-uhci14:
1944208XT-PICide015:
3562845XT-PICide1NMI:
0ERR:
0
这一次,中断数字是从0到15的十进制数。
同样,将这些中断与清单5所示的PC标准IRQ分配进行比较。
清单5.标准IRQ设置
IRQ0-SystemTimerIRQ1-KeyboardIRQ2(9)-VideoCardIRQ3-COM2,COM4IRQ4-COM1,COM3IRQ5-Available(LPT2orSoundCard)IRQ6-FloppyDiskControllerIRQ7-LPT1IRQ8-Real-TimeClockIRQ9-RedirectedIRQ2IRQ10-AvailableIRQ11-AvailableIRQ12-PS/2MouseIRQ13-MathCo-ProcessorIRQ14-HardDiskControllerIRQ15-Available
最初,每个设备都有自己的私有IRQ。
做为示例,注意,在清单5中,IRQ5通常用于声卡或者第二个并行端口(打印机)。
如果两个都要使用,那么不得不去寻找一个能够配置的卡(通常是通过硬件跳线设置)来使用另一个IRQ,比如IRQ15。
目前的PCI设备是共享IRQ的,所以,当某个设备中断CPU时,会有一个中断处理程序检查它并判断那个中断是否为它所用的中断,如果不是,则将它传递给链中的下一个处理程序。
清单4和5并没有向我们展示这种共享。
在后面的教程中我们将会学习grep命令,不过,现在我们可以使用它来过滤dmesg命令的输出,来查看关于IRQ的引导消息,如清单6所示。
在此突出显示了共享的中断。
清单6.引导过程中发现的中断
[ian@lyrebirdian]$dmesg|grep-iirqPCI:
Discoveredprimarypeerbus01[IRQ]PCI:
UsingIRQrouterPIIX[8086/24c0]at00:
1f.0PCI:
FoundIRQ5fordevice00:
1f.1PCI:
SharingIRQ5with00:
1d.2Serialdriverversion5.05c(2001-07-08)withMANY_PORTSMULTIPORTSHARE_IRQSERIAL_PCIISAPNPenabledttyS0at0x03f8(irq=4)isa16550AttyS1at0x02f8(irq=3)isa16550APCI:
FoundIRQ5fordevice00:
1f.1PCI:
SharingIRQ5with00:
1d.2ICH4:
not100%nativemode:
willprobeirqslateride0at0x1f0-0x1f7,0x3f6onirq14ide1at0x170-0x177,0x376onirq15PCI:
FoundIRQ11fordevice00:
1d.0PCI:
SharingIRQ11with00:
02.0usb-uhci.c:
USBUHCIatI/O0x1800,IRQ11PCI:
FoundIRQ10fordevice00:
1d.1usb-uhci.c:
USBUHCIatI/O0x1820,IRQ10PCI:
FoundIRQ5fordevice00:
1d.2PCI:
SharingIRQ5with00:
1f.1usb-uhci.c:
USBUHCIatI/O0x1840,IRQ5PCI:
FoundIRQ9fordevice00:
1d.7ehci-hcd00:
1d.7:
irq9,pcimemf885d000parport0:
irq7detectedPCI:
FoundIRQ9fordevice02:
08.0PCI:
FoundIRQ9fordevice02:
08.0parport0:
irq7detectedPCI:
FoundIRQ11fordevice00:
02.0PCI:
SharingIRQ11with00:
1d.0PCI:
FoundIRQ9fordevice00:
1f.5PCI:
SharingIRQ9with00:
1f.3i810:
IntelICH4foundatIO0x18c0and0x1c00,MEM0xc0080c00and0xc0080800,IRQ9
DMA
先前提及的与外围设备通过IO端口进行的通信,每次传递一个或者两个字节。
对于快速的设备,服务中断会用掉大量CPU处理能力。
更快的方法是使用直接内存访问(DirectMemoryAccess,DMA),使用很少IO指令告诉设备到RAM中哪个位置去读或写数据,然后DMA控制器提供RAM和外围设备之间数据实际传输的硬件管理。
谁可以猜出在哪里可以找到关于正在使用的DMA通道的信息,请举手。
如果您说它是在/proc/dma中,那么就说对了。
运行cat/proc/dma命令,可以看到如清单7所示的输出。
清单7./proc/dma
4:
cascade
那就足够了吗?
重要的是要记住,当IO实际发生时,大部分设备只请求一个或者有限数目的DMA通道,所以,在我们的示例中/proc/dma经常看起来是几乎是空的。
也可以像前面处理IRQ那样,扫描引导消息来查找具有DMA能力设备的证据。
清单8./proc/dma
[ian@lyrebirdian]$dmesg|grep-idmaide0:
BM-DMAat0x1860-0x1867,BIOSsettings:
hda:
DMA,hdb:
pioide1:
BM-DMAat0x1868-0x186f,BIOSsettings:
hdc:
DMA,hdd:
DMAhda:
312581808sectors(160042MB)w/8192KiBCache,CHS=19457/255/63,UDMA(100)hdc:
398297088sectors(203928MB)w/7936KiBCache,CHS=24792/255/63,UDMA(33)ehci-hcd00:
1d.7:
enabled64bitPCIDMA
即插即用(Plugandplay)
早期的PC为特定设备分配固定的端口号和IRQ,比如键盘或者并行打印端口。
这导致难以添加新设备或者使用两个相同类型的设备,比如两个调制解调器或者两个打印机。
第一个串行端口通常称为COM1,第二个称为COM2。
Linux系统通常将它们称为ttyS0和ttyS1。
例如,某些可配置的卡通常具有硬件跳线
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 设备 驱动程序
![提示](https://static.bingdoc.com/images/bang_tan.gif)