0%

linux输入输出系统

2020年5月12日 下午7:44

设备控制器:这是个硬件

  1. 职责:
    1. 字面意思,告诉你如何控制设备
  2. 通信方式:
    1. CPU 如何同控制器的寄存器和数据缓冲区进行通信呢?
      1. 每个控制寄存器被分配一个 I_O 端口,我们可以通过特殊的汇编指令(例如 in_out 类似的指令)操作这些寄存器。
      2. 数据缓冲区,可内存映射 I/O,可以分配一段内存空间给它,就像读写内存一样读写数据缓冲区。如果你去看内存空间的话,有一个原来我们没有讲过的区域 ioremap,就是做这个的。
    2. 控制器的寄存器一般会有状态标志位,可以通过检测状态标志位,来确定输入或者输出操作是否完成。
      1. 第一种方式就是轮询等待,就是一直查,一直查,直到完成。
      2. 当然这种方式很不好,于是我们有了第二种方式,就是可以通过中断的方式,通知操作系统输入输出操作已经完成。
  3. 输入输出设备我们大致可以分为两类:块设备(Block Device)和字符设备(Character Device)。
    1. 块设备将信息存储在固定大小的块中,每个块都有自己的地址。硬盘就是常见的块设备。
    2. 字符设备发送或接收的是字节流。而不用考虑任何块结构,没有办法寻址。鼠标就是常见的字符设备。

中断控制器:硬件

  1. 职责:
    1. 为了响应中断,我们一般会有一个硬件的中断控制器,当设备完成任务后触发中断到中断控制器,中断控制器就通知 CPU,一个中断产生了,CPU 需要停下当前手里的事情来处理中断。

DMA:硬件

  1. 职责:
    1. 有的设备需要读取或者写入大量数据
    2. CPU 只需要对 DMA 控制器下指令,说它想读取多少数据,放在内存的某个地方就可以了,接下来 DMA 控制器会发指令给磁盘控制器,读取磁盘上的数据到指定的内存位置,传输完毕之后,DMA 控制器发中断通知 CPU 指令完成,CPU 就可以直接用内存里面现成的数据了。

驱动程序:软件

  1. 职责:
    1. 向上:操作系统的内核代码可以像调用本地代码一样调用驱动程序的代码
    2. 向下:而驱动程序的代码需要发出特殊的面向设备控制器的指令,才能操作设备控制器。
    3. 既然设备驱动程序是用来对接设备控制器的,中断处理也应该在设备驱动里面完成。
  2. 工作流程:
    1. 一般的流程是,一个设备驱动程序初始化的时候,要先注册一个该设备的中断处理函数。咱们讲进程切换的时候说过,中断返回的那一刻是进程切换的时机。不知道你还记不记得,中断的时候,触发的函数是 do_IRQ。这个函数是中断处理的统一入口。在这个函数里面,我们可以找到设备驱动程序注册的中断处理函数 Handler,然后执行它进行中断处理。

块设备层:软件:

  1. 职责:
    1. 因为块设备类型非常多,而 Linux 操作系统里面一切是文件。我们也不想文件系统以下,就直接对接各种各样的块设备驱动程序,这样会使得文件系统的复杂度非常高。

文件系统:软件

  1. 职责:
    1. 到通用设备层,我们只是对linux内核来说,屏蔽了设备的区别,但是对linux系统的使用者来说,目前还无法操作硬件
    2. 这里我们就需要把文件系统当做是对用户态的封装接口
  2. 文件系统对设备的管理方式:
    1. 特殊的文件系统:devtmpfs 建立与某个设备驱动程序的连接
      1. 这个设备本身也不对应硬盘上的任何一个文件,_dev_sdb 其实是在一个特殊的文件系统 devtmpfs 中。
      2. 这个设备特殊文件_dev_sdb也有 inode,但是它不关联到硬盘或任何其他存储介质上的数据,而是建立了与某个设备驱动程序的连接。
    2. 特殊的文件系统:sysfs 管理设备
      1. 管理设备的文件系统,也就是 /sys 路径下面的 sysfs 文件系统。它把实际连接到系统上的设备和总线组成了一个分层的文件系统。这个文件系统是当前系统上实际的设备数的真实反映。
      2. 有了 sysfs 以后,我们还需要一个守护进程 udev。当一个设备新插入系统的时候,内核会检测到这个设备,并会创建一个内核对象 kobject 。 这个对象通过 sysfs 文件系统展现到用户层,同时内核还向用户空间发送一个热插拔消息。udevd 会监听这些消息,在 /dev 中创建对应的文件。