1 软件是如何访问硬件的
操作系统作为硬件层的上层,是对硬件的管理和抽象。对于操作系统上面的运行库和应用程序来说,他们希望看到的是一个统一的硬件访问模式。作为应用程序开发者,不希望在开发应用程序的时候直接读写硬件端口、处理硬件中断等这些繁琐的事情。这些繁琐的硬件细节全都交给了操作系统,具体的讲是操作系统中的硬件驱动
驱动程序可以看做是操作系统的一部分,往往跟操作系统内核一起运行在特权级,但又有独立性,使得驱动程序很灵活。
硬件是各种各样的,操作系统不可能随时更新各种硬件的驱动方法,总不能刚出来某个硬件,OS开发者就写驱动。所以就需要各种硬件适配设备,也就是IO接口。接口就是标准,只要硬件生产商按照接口来工作,就能实现通用。
硬件在输入输出上可以分为串行和并行,对应的接口就是串行接口和并行接口。串行硬件通过串行接口与CPU通信,CPU也可以通过串行接口与串行设备进行通信。并行设备类似。
访问外部硬件有两种方式
-
将某个外设的内存映射到一定范围的地址空间中,CPU通过地址总线访问该内存区域时会落到外设的内存中,这种映射让CPU访问外设的内存就如同访问主板上的物理内存一样。
- 比如显卡;显卡就是显示器的适配器,CPU不直接和显示器交互,它只和显卡通信,显卡上有片内存叫显存,往这片内存上写字节便是往屏幕上打印内容。
-
外设通过IO接口与CPU通信,CPU访问外设,就是访问IO接口,由IO接口将信息传递给另一端的外设。也就是说CPU从来不知道有这些设备的存在,它只知道自己操作的IO接口。
-
如何访问到IO接口?IO接口上有一些寄存器,访问IO接口本质上就是访问这些寄存器,这些寄存器就是人们常说的端口,这些端口是IO接口给提供的接口,(接口提供接口)接口电路有自己的系统,看到寄存器中写了什么就做出相应的反应。
-
在x86平台上,共有65536个硬件端口寄存器,不同的硬件被分配到了不同的IO端口地址,CPU提供了两条专门的指令
in
和out
来实现对硬件端口的读和写。 -
举个例子:对IDE(电子集成驱动器)接口来说,有两个通道,分别为IDE0和IDE1,每个通道上可以连接两个设备,分别为Master和Slave,一个PC中最多可以有4个IDE设备。假设我们文件位于IDE0的Master硬盘上,在PC中,IDE0通道的IO端口地址是
0x1F0~0x1F7
及0x376~0x377
,通过读写这些端口就能与IDE硬盘进行通信。以读取1000号逻辑扇区开始的8个扇区为例:-
0x1F3~0x1F6
4个字节(32位寻址空间)的端口地址是用来写入LBA(逻辑区块,磁盘的逻辑地址,用于和实际的物理地址映射,转换成盘面、磁道等位置)地址的,那么1000号逻辑扇区的LBA地址为0x0000003E8
,所以我们需要往0x1F3、0x1F4
写入0x00
,往0x1F5
写入0x03
往0x1F6
写入0xE8
-
0x1F2
这个地址用来写入命令所需要读写的扇区数,比如读取8个扇区即写入8-
0x1F7
这个地址用来写入要执行的操作的命令码,对于读取操作来说,命令字为0x20
所以指令为out 0x1F3, 0x00 out 0x1F4, 0x00 out 0x1F5, 0x03 out 0x1F6, 0xE8 out 0x1F2, 0x08 out 0x1F7, 0x20
-
-
-