- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
I-O端口和I-O内存节选
I/O端口和I/O内存节选
9.2.1 I/O端口
I/O端口和I/O内存
设备驱动程序要直接访问外设或其接口卡上的物理电路,这部分通常都是以寄存器的形式出现。外设寄存器也称为I/O端口, 通常包括:控制寄存器、状态寄存器和数据寄存器三大类。
I/O编程提供统一的方法,每个设备的I/O 端口都被组织成如图9.3所示的一组专用寄存器。CPU把要发给设备的命令写入控制寄存器,并从状态寄存器中读出表示设备内部状态的值。CPU还可以通过读取输入寄存器的内容从设备取得数据,也可以通过向输出寄存器中写入字节而把数据输出到设备。
图9.3 专用I/O端口
根据访问外设寄存器的不同方式,可以把CPU分成两大类。一类CPU(如M68K,Power PC等)把这些寄存器看作内存的一部分,寄存器参与内存统一编址,访问寄存器只需使用一般的内存指令进行,即这类CPU不需要有专门用于设备I/O的指 令。这就是所谓的“I/O内存”方式。另一类CPU(如X86)将外设的寄存器看成一个独立的地址空间,这样访问内存的指令就不能用来访问这些寄存器,因此要为对外设寄存器的读/写设置专用指令,如IN和OUT指令。这就是所谓的“ I/O端口”方式 。
然而,用于I/O指令的“地址空间”相对来说是很小的。事实上,现在x86的I/O地址空间已经非常拥挤。但 是,随着计算机技术的发展,这种只能对外设中的几个寄存器进行操作的方式,已经无法满足实际需要了。而实际上,需求在不断发生变化,例 如,在PC上可以插上一块图形卡,有2MB的存储空间,甚至可能还带有ROM,其中装有可执行代码。自从PCI总线出现后,无论CPU的设计采用I/O 端口方式,还是I/O内存方式,都必须将外设卡上的存储器映射到内存空间,实际上是采用了虚存空间的手段,这样的映射是通过ioremap()来建立的。
2.??访问I/O端口? ?in、out、ins和outs汇编语言指令都可以访问I/O端口。内核中包含了以下辅助函数来简化这种访问:
inb( )、inw( )、inl( ),分别从I/O端口读取1、2或4个连续字节。后缀“b”、“w”、“l”分别代表一个字节(8位)、一个字(16位)以及一个长整型(32位)。
inb_p( )、inw_p( )、inl_p( )分别从I/O端口读取1、2或4个连续字节,然后执行一条“哑元(dummy,即空指令)”指令使CPU暂停。
outb( )、outw( )、outl( )分别向一个I/O端口写入1、2或4个连续字节。
outb_p( )、outw_p( )、outl_p( )分别向一个I/O端口写入1、2或4个连续字节,然后执行一条“哑元”指令使CPU暂停。
insb( )、insw( )、insl( )分别从I/O端口读入以1、2或4个字节为一组的连续字节序列。字节序列的长度由该函数的参数给出。
outsb( )、outsw( )、outsl( )分别向I/O端口写入以1、2或4个字节为一组的连续字节序列。
虽然访问I/O端口非常简单,但是检测哪些I/O端口已经分配给I/O设备可能就不这么简单了,对基于ISA总线的系统来说更是如此。通常,I/O设备驱动程序为了探测硬件设备,需要盲目地向某一I/O端口写入数据;但是,如果其他硬件设备已经使用这个端口,那么系统就会崩溃。为了防止这种情况的发生,内核必须使用“资源”来记录分配给每个硬件设备的I/O端口。
资源表示某个实体的一部分,这部分被互斥地分配给设备驱动程序。在这里,资源表示I/O端口地址的一个范围。每个资源对应的信息存放在resource数据结构中:
struct resource {
?? resource_size_t start;? ?? ?? ?resource_size_t end;? ?? ?? ?const char *name;? ?? ?? ?unsigned long flags;? ?? ?? ?struct resource *parent, *sibling, *child;};其字段如表1所示。所有的同种资源都插入到一个树型数据结构(父亲、兄弟和孩子)中;例如,表示I/O端口地址范围的所有资源都包括在一个根节点为ioport_resource的树中。表1: resource数据结构中的字段
类型 字段 描述 const char * name 资源拥有者的名字 unsigned long start 资源范围的开始 unsigned long end 资源范围的结束 unsigned long flags 各种标志 struct resource * parent 指向资源树中父亲的指针 struct resource * sibling 指向资源树中兄弟的指
文档评论(0)