声明:内容搬自阿三哥网站,只是翻译了一下。侵删。https://embetronicx.com/tutorials/linux/device-drivers/
正文如下:
这是“linux设备驱动系列”的教程。本系列的目的是提供简单实用的示例,使每个人都能以简单的方式理解这些概念。所以让我们进入“linux设备驱动第一部分-简介”。在我们进行编程之前,最好是先了解一些关于linux以及linux驱动的基础知识。接下来我们简单了解一下linux。
内容速览
·1 linux设备驱动第一部分-简介
·2 linux-简介
·2.1 linux 架构
·2.1.1 内核空间
·2.1.2 用户空间
·1 linux设备驱动第一部分-简介
·2 linux-简介
linux是基于UNIX的免费开源操作系统,1991年由Linus Torvalds创建。用户可以为计算机和其他设备修改和创建源代码的变体,即所谓的发行版(distribution)。
·2.1 linux 架构
linux主要分为用户空间(User Space)和内核空间(Kernel Space)。这两个空间通过“系统调用接口”进行交互。系统调用接口是为“用户空间应用程序”定义好的、成熟的linux内核接口。下边的图片会使你有些基本的认识。
·2.1.1 内核空间
内核空间是“内核(操作系统的核心)运行”和“提供内核服务”的地方。
·2.1.2 用户空间
用户空间是“用户应用程序”运行的地方。
·3 linux 内核模块
内核模块是能根据需求加载、卸载的一段代码。它不用重启系统就能扩展内核的功能。
自定义的代码要添加到内核里有两种方法:
- 最简单的方法是在内核树中添加代码,然后重新编译内核。
- 一个更有效的方式是在系统运行时向内核中添加代码。这个过程叫做“加载模块”。这个加载的模块是指我们往内核中添加的代码。
由于我们是在运行时加载这些代码,而且这些代码不是正式的linux内核的一部分,我们称其为“可加载内核模块(LKM--Loadable kernel module),使其与“基本模块”区别开来。基本模块位于“/boot”目录下,并且每当我们启动系统时都会被加载;而LKM是在基本内核已经加载之后才会加载的。尽管如此,LKM是内核里非常重要的一部分,它与基本模块通信以实现其功能。
LKM可以完成很多任务,但是这些任务基本分为三大类,
-
设备驱动程序(device driver)
-
文件系统驱动程序(filesystem driver)
-
系统调用 (system calls)
·3.1 设备驱动程序
设备驱动程序(device driver)是为特定的硬件设计的。内核用它来与硬件通信,而不用知道硬件如何工作的任何细节。
·3.2 文件系统驱动程序
文件系统驱动程序把“文件系统”(通常是一块硬盘驱动器里的内容)的内容解释为文件、目录等等。有很多种不同的方法来存储文件和目录;比如存储在“硬盘驱动器(disk drive)”中,“网络服务器”中等等。不管用那种方法,你都需要文件系统驱动程序。例如,ext2文件系统的文件系统驱动程序在linux磁盘驱动器上普遍使用。同样,在MS-DOS文件系统中,NFS也被普遍使用。
·3.3 系统调用
用户空间程序是通过系统调用从内核中获取服务(services)的。例如,利用系统调用读取文件,创建进程,关闭系统。大多数系统调用都是系统不可或缺的,并且非常标准(standard),所以总是被内置在基本内核中(没有LKM选项)。
但是你可以自己发明一种系统调用,使其像LKM一样加载。或者你不喜欢linux这种做事的方式,用你自己的LKM覆盖现有的系统调用。
·3.4 LKM的优势
- 一个最主要的优势就是:每次我们添加一个新设备或者升级一个旧设备的时候不用重新构建内核(rebuild kernel)。这节省了时间,同时也可以保持我们的基本内核没有错误(error-free)。
- LKM非常的灵活,只需一行代码就可以加载、卸载。这节省了内存,我们可以只在需要这个模块的时候把它加载到内核中。
·3.5 内核模型与用户程序之间的区别
- 内核模块有单独的地址空间。模块在内核空间运行。应用程序在用户空间运行。这保护系统软件不受用户程序的影响。内核空间和用户空间有他们自己分别的内存地址空间。
- 内核模块有更高的执行权限。相比于用户空间运行的代码,在内核空间运行的代码有执行特权。
- 内核模块不是顺序执行的。一个用户程序通常是顺序执行的,从头到尾地完成一项任务。内核模块不是顺序执行的。内核模块注册自己是为了服务未来的请求(requests)。
- 内核模块使用不同的头文件。内核模块所用的一套头文件和用户程序是不同的。
·3.6 内核驱动与内核模块之间的区别
- 内核模块是在运行时可以被嵌入内核的一段编译好的代码, 例如使用 insmod 和 modprobe 命令来加载内核模块。
- 驱动程序是在内核里运行的一段代码,它直接与硬件进行交流。它“驱动”着硬件。在你电脑里的每一块硬件都有与之对应的驱动程序。
·4 设备驱动程序
设备驱动程序是软件应用程序的一种特殊形式,它被设计用来支持与硬件设备的交互。没有所需的设备驱动程序,相应的硬件设备就不会工作。
设备驱动程序通常通过与硬件相连的通信子系统(communication subsystem)或计算机总线(computer bus)与硬件进行通信。设备驱动程序是特定于操作系统并依赖于硬件的。设备驱动程序在“硬件设备”与使用硬件设备的“程序或者操作系统”之间扮演一位翻译官。
·4.1 类型
按传统分类,设备可以分为一下三类:
- 字符设备
- 块设备
- 网络设备
在linux系统中,一切皆文件。我的意思是linux把一切都当作文件看待,甚至硬件设备也是如此。
【下面的字符设备小节和块设备小节中,原作者都是用“文件(file)”一次来代替“设备(device)”。】
·4.2 字符设备
字符文件是一个字符一个字符地读/写数据的硬件文件。一些经典的例子是键盘、鼠标、串行打印机。如果用户使用一个字符文件来写入数据,那么其他用户就不能使用这个字符文件来写入数据;这将阻塞(block)其他用户的访问(access)。字符文件使用“同步技术(Synchronize Technic)”来写入数据。
你可以观察到,字符文件是用与通信目的的,它们不能被挂载(mount)。
·4.3 块设备
块文件是一块一块地而不是逐字符地读/写数据的硬件文件。这类型的文件在我们想批量地读/写数据是非常有用。所有的磁盘,例如HDD(Hard Disk Drive),USB, CDROM,都是块设备。这就是为什么我们在格式化磁盘时要考虑块大小(block size)。写入数据是用“异步”方式完成的,它是一种CPU密集型活动。
这类设备文件用来在真实的硬件中存储数据,并且可以被挂载;这样我们就可以访问已经被写入的数据。
·4.4 网络设备
就linux网络子系统而言,网络设备是发送和接受数据包的实体(entity)。它通常是一个物理设备,比如以太网卡。但是有些网络设备是只是软件;比如用于给自己发送数据的回路(loopback)设备。
--------------------------------分割线------------------------------
我们关于“linux和设备驱动程序”的基础知识就到这里啦。我们在下一节教程中将会进入“linux设备驱动程序编写”~~~~
在那之前,记得点这里"linux设备驱动程序开发环境搭建"(命令 ">>uname -r " 来得到系统的内核版本),提前搭建好基于linux的设备驱动开发环境吧~~~