1、Linux设备驱动的基本概念
设备驱动程序(Device Driver),简称驱动程序(Driver)。它是一个允许计算机软件与硬件交互的程序。这种程序建立了一个硬件与硬件,或硬件与软件沟通的界面。CPU经由主板上的总线(Bus)或其他沟通子系统(Subsystem)与硬件形成连接,这样的连接使得硬件设备之间的数据交换成为可能。
驱动程序是提供硬件到操作系统的一个接口,并且协调二者之间的关系。
计算机系统的主要硬件由CPU、存储器和外部设备组成。驱动程序的对象一般是存储器和外部设备。Linux将这些设备分为3大类,分别是字符设备、块设备、网络设备。
1、字符设备
字符设备是指那些能一个字节一个字节读取数据的设备,如LED灯、键盘、鼠标等。字符设备一般需要在驱动层实现open()、close()、read()、write()、ioctl()等函数。这些函数最终将被文件系统中的相关函数调用。内核为字符设备对应一个文件,/dev/console。对字符设备的操作可以用个字符设备文件/dev/console来进行。
2、块设备
在linux系统中,进行块设备读写时,每次只能传输一个或者多个块。
3、网络设备
网络设备主要负责主机之间的数据交换。
用户态和内核态:
用户态处理上层的软件工作。
内核态用来管理用户态的程序,完成用户态请求的工作。
模块机制
模块是可以在运行时加入内核的代码。模块在内核启动时装载称为静态装载,在内核已经运行时装载称为动态装载。
驱动开发需掌握的知识:
1、C
2、硬件基础。不要求设计电路,但对芯片手册上描述的接口设备有清楚的认识。比如SRAM、Flash、UART、IIC、USB等。
3、Linux内核源代码。一些重要的数据结构和函数。
4、多任务程序设计的能力。
驱动开发与应用开发的差异:
1、内核及驱动程序开发时不能访问C库。因为C库是使用内核中的系统调用来实现的,而且是在用户空间实现的。
2、内核及驱动程序开发时必须使用GNU C,因为Linux从一开始就使用GNU C。
3、内核支持异步终端、抢占和SMP,故必须注意同步和并发。
4、内核只有一个很小的定长堆栈。
5、内核及驱动程序开发时缺乏像用户空间那样的内存保护机制。
6、内核及驱动程序开发时浮点数很难使用,应该使用整形数。
7、内核及驱动程序开发要考虑可移植性。
2、Linux 源码结构分析
1、arch目录
包含与体系结构相关的代码,每一种平台都有一种相应的目录。
2、drivers目录
包含了Linux内核支持的大部分驱动程序。
3、fs目录
所有文件系统相关的代码。
4、其他目录
3、内核配置选项:
为简化内核源代码的编译,有如下机制:
1、Makefile 文件:它的作用是根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把目标代码链接到一起,最终形成Linux内核二进制文件。由于Linux内核源代码是按照树形结构组织的,所以Makefile也被分布在目录树中。
2、Kconfig 文件:它的作用是为用户提供一个层次化的配置选项集。make menuconfig 命令通过分布在各个子目录中的Kconfig 文件构建配置用户界面。
3、配置文件(.config):当用户配置完后,将配置信息保存在.config 文件中。
4、配置工具:包括配置命令解释器和配置用户界面。
当执行menuconfig 命令时,配置程序会依次从目录由浅入深查找每一个Kbuild文件,依照这个文件中的数据生成一个配置菜单。Kbuild像是一个分布在各个目录中的配置数据库,通过这个数据库可以生成配置菜单。在配置菜单中根据需要配置完成后会在主目录下生成一个.config文件,此文件保存了配置信息。
然后执行make命令,会依赖生成的.config文件,以确定哪些功能将编译入内核中,哪些功能不编译入内核中。然后递归地进入每一个目录,寻找Makefile文件,编译相应的代码。
3.1、常规配置: 包含关于内核的大量配置,(代码成熟度、版本信息、模块配置)
3.2、版本信息:
3.3、模块配置:
3.4、块设备层配置:包含对系统使用的块设备的配置,主要包含调度器的配置,硬盘设备的配置。
3.5、CPU类型和特性配置:
3.6、电源管理配置:
3.7、网络配置:
3.8、设备驱动配置:
通用设备:
字符设备配置:
多媒体设备驱动配置:
USB设备驱动配置:
3.9、文件系统配置:
4、嵌入式文件系统基本知识:
Linux支持多种文件系统,包括 ext2、ext3、vfat、ntfs、iso9660、jffs、romfs、cramfs、nfs 等。为了统一管理,Linux引入虚拟文件系统 VFS(Virtual FILE System)。
Linux 文件系统由 4 层组成,分别是用户层、内核层、驱动层、和硬件层。
用户层:为用户提供一个操作接口。
内核层:实现了各种文件系统。
驱动层:是块设备的驱动程序。
硬件层:是嵌入式系统使用的几种存储器。
Linux启动时,第一个必须挂载的是 根文件系统。
嵌入式系统的存储介质:
JFFS文件系统:主要用于NOR型Flash存储器。其基于MTD驱动层。可读写、支持数据压缩、基于哈希表的日志型文件系统,并提供了崩溃掉电安全保护,提供“写平衡”支持。
YAFFS文件系统:专门为NAND Flash存储器设计的嵌入式文件系统。适用于大容量的存储设备。速度快,占用内存少,不支持压缩和只支持NAND Flash存储器。
根文件系统
根文件系统被存储在Flash存储器中,存储器被分为多个分区,(分区1,分区2,分区3等。)
分区1一般存储Linux内核映像文件,分区2存放根文件系统,根文件系统中存放着系统启动必须的文件和程序(包括提供用户界面的shell程序、应用程序依赖的库、配置文件等)。
内核启动后运行的第一个程序是init,其将启动根文件系统中的shell程序,给用户提供一个友好的操作界面。
构建根文件系统:
第一种方法:下载相应的命令源码,并移植到处理器架构平台上。
第二种方法:使用开源工具构建。(BusyBox、TinyLogin、Embutils)