Ioctl

背景

传统的操作系统可以分成两层，用户层和内核层。应用程序代码比如编辑器，处于用户层，然而系统底层程序，比如网络栈，处于内核层。内核代码处理敏感资源同时在不同应用程序中间提供了安全且可信的隔离，出于此，操作系统要阻止用户态的程序直接访问内核资源。用户空间的程序通常发出一个给内核的请求，该请求称为系统调用，它的实现代码在内核层。系统调用采取“系统调用增量”的方式，用递增的序号指示系统调用。举个例子，exit()可能是1，write()可能是4。系统调用增量能通过这样的不同数值找到对应的被请求的内核函数，传统的操作系统通常用这种方式给用户空间提供了上百个系统调用。操作系统提供了内核访问标准外部设备的系统调用，因为大多数硬件设备只能够在内核空间内直接寻址,但是当访问非标准硬件设备这些系统调用显得不合适,有时候用户模式可能需要直接访问设备，比如，一个系统管理员可能要修改网卡的配置。现代操作系统提供了各种各样设备的支持，有一些设备可能没有被内核设计者考虑到，如此一来提供一个这样的系统调用来使用设备就变得不可能了。 为了解决这个问题，内核被设计成可扩展的，可以加入一个称为设备驱动的模块，驱动的代码允许在内核空间运行而且可以对设备直接寻址。一个Ioctl接口是一个独立的系统调用，通过它用户空间可以跟设备驱动沟通。对设备驱动的请求是一个以设备和请求号码为参数的Ioctl调用，如此内核就允许用户空间访问设备驱动进而访问设备而不需要了解具体的设备细节，同时也不需要一大堆针对不同设备的系统调用。