最近需要写个驱动,也看了LDD,也看了其他的blog。其实对于那些简单的一个字符设备的设计流程慢慢lvlv,大概知道这个流程是怎么跑的。但是还是不够流畅,对于驱动与内核的认识还是存在一些混淆。这里来做个记录。
参考的资料是《Linux设备驱动开发详解》
1、驱动是什么?
其实我开始的时候把驱动总和内核搞混。多余我就不啰嗦了,书里面有,微信读书可以阅读,我也买了本实物书。
- 1、 如果你以前玩过单片机,裸板不带操作系统的,你写的那些代码直接操作硬件去完成一些功能,这些代码就是驱动。
(当然我们平时在实现的时候,应用层和设备驱动搞到一起了。)
- 2、如果有操作系统,那么驱动程序就被挡住了,用户态的是看不到的。长这样的。
有了操作系统,我们不但要把硬件操作加到操作系统中,还需要提供给操作系统来调用我驱动的接口。为什么? - 3、 一个CPU中,是包含了核ARM和其他的外设,这里的外设不仅仅是键盘鼠标等,还包括了除去cpu核以外的GPU、DSP、GPS、Wifi等等。有没有想起,这些外设其实都是需要驱动的。驱动针对的对象是存储器和外设(包括CPU内部集成的存储器和外设),而不是针对CPU内核。Linux将存储器和外设分为3个基础大类。
有了上面三点,就可以说说为什么需要驱动?为什么要把驱动加到操作系统?
前一个问题不回答
第二个,这个首先是因为操作系统的优点:多任务、内存管理。而操作系统对于驱动方面提供的好处,就是可以通过操作系统定义的接口实现时,就算是设备变了,应用也不需要变。就像是你换了个显卡,但是显卡都是按照操作系统提供的标准进行定义的接口,所以就算是显卡换了,但是你上层原来安装的应用还是能用。(典型的依赖倒置设计模式)
这里有没有想起,我们有时候换了设备,或者热插拔设备,都会提示你驱动安装中,这个过程可能就是设备的驱动注册到操作系统,然后你就可以继续使用你的应用。没有说换个设备,也让你安装个对应的应用吧。其实就是增加复用性与解耦。用稳定的操作系统,在操作系统的两头是可能会变化的东西,但是变化不会影响两端的使用。
(脑子里想想一个管道)
2、linux内核与linux操作系统的关系?
内核是操作系统的核心。内核是操作系统执行的第一道程序,被率先加载到内存中开始系统行为。内核始终保持在主内存中直到系统被关闭。内核将用户输入的命令转换成计算机硬件能理解的机器语言。
**内核是系统应用软件和硬件的桥梁。内核直接与硬件联系,并告之它由应用软件发起的请求。**操作系统不能脱离内核工作,内核是系统正常运行最重要的程序。
内核的主要职责是:进程管理、磁盘管理、任务调度、内存管理等
操作系统(operating system)是用来管理计算机系统资源的软件,内核是用户和系统硬件的桥梁。操作系统提供的接口允许用户直接看到其输入命令的响应结果,例如Window的命令行cmd和Linux的Shell终端。没有操作系统,系统就不可能运行,部分嵌入式系统看似没有操作系统,但仍然对硬件作了一层简单封装,也可理解为Tiny OS。操作系统的主要职责是创建应用软件可以运行的环境。
总的说来,一个操作系统包含了内核(是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件)以及其他计算机系统所必须的组件(如函数库、编译器、调式工具、文本编辑器、网站服务器,以及一个Unix的使用者接口(Unix shell)等,这些都是操作系统的一部分,而且每一个模块如编译器都是一个单独的进程,运行在操作系统中)。
3、驱动处在整个系统的那个地方呢?
驱动分为块、字符、网络设备三种,字符是串行顺序访问:鼠标等,块是任意顺序访问:硬盘、eMMC等。网络设备见名知意,使用套接字。
到这里你应该就知道了驱动是个什么,以及处在整个系统的位置。
4、驱动工程师应该学到什么?
●编写Linux设备驱动要求工程师有非常好的硬件基础,懂得SRAM、Flash、SDRAM、磁盘的读写方式,UART、IC、USB等设备的接口以及轮询、中断、DMA的原理,PCI总线的工作方式以及CPU的内存管理单元(MMU)等。
●编写Linux设备驱动要求工程师有非常好的C语言基础,能灵活地运用C语言的结构体、指针、函数指针及内存动态申请和释放等。
●编写Linux设备驱动要求工程师有一定的Linux内核基础,虽然并不要求工程师对内核各个部分有深入的研究,但至少要明白驱动与内核的接口。尤其是对于块设备、网络设备、Flash 设备、串口设备等复杂设备,内核定义的驱动体系结构本身就非常复杂。
●编写Linux设备驱动要求工程师有非常好的多任务并发控制和同步的基础,因为在驱动中会大量使用自旋锁、互斥、信号量、等待队列等并发与同步机制。
想啰嗦一下的是第三点,有linux内核的基础,这是因为linux内核是我们前面知道是包括了进程管理、磁盘管理、任务调度、内存管理等。而我们的设备映射的都是文件,设备的操作各种都是涉及到这几方面,所以要对内核的这些进行学习。
linux的内核中有很多个驱动子系统。(驱动子系统实现对驱动设备进行管理比如eMMC),因此下一章,先来看看驱动的软件架构是什么?
参考资料:
《Linux设备驱动开发详解》