读《Linux 设备驱动 Edition 3》第一天

来源:互联网 发布:装修行业网络推广方案 编辑:程序博客网 时间:2024/06/03 11:16

在机顶盒工作的这几天,很多有关于嵌入式的知识都模糊起来。,因此,在工作闲暇之余,开始重新阅读嵌入式方面的知识,着重在TCP/IP、设备驱动、内存管理、进程间通信(IIC、IPC、UART)、中断、锁等。具体的等以后学习再逐一记录。至于书籍的选取,多来自与CSDN和知乎大神的分享,Linux 设备驱动 Edition 3 是今天的第一本。文章的最后会贴出书籍封面供参考。

首先,驱动程序是基于内核而写的模块化程序,因此了解内核是第一步。内核大致可以分为以下几个部分:内存管理、进程管理、设备控制、网络和文件系统。内核的划分表示了负责特定任务的不同类别的模块。而驱动可以分为三类:字符设备、块设备和网络设备。前两者的区别在于设备驱动读取数据的形式不同,字符设备是以一个字节流来存取的设备,而块设备则是以一个或多个长度为512(或一个更大的2的幂级数)的块形数据。网络设备至今未曾涉及,我在网上找来了三者比较官方的定义:(1)块设备    设备以数据块的形式存放数据,如NAND Flash以页为单位存储数据,并采用mount方式挂载块设备。块设备还需通过建立Flash文件系统,如YAFFS、JFFS等,用于规范文件和目录在存储介质上的组织。这类型的设备已经在Linux内核中加载,不需要再做移植。(2)网络设备   网络设备是面向数据包的接收和发送而设计的。它并不对应于文件系统(/dev目录下)的节点,而是由系统分配一个唯一的名字(如eth0)。(3)字符设备  字符设备指能够像字节流串行顺序依次进行访问的设备,对它的读写是以字节为单位。除了网络设备外,字符设备和块设备都是通过文件系统的系统调用接口open()、close()、write()、read()等函数既可以访问,应用程序可以通过打开设备文件(如UART0设备:/dev/ttyS0)来访问该设备。
由于以前在2.6.35.7的内核上进行过多个驱动程序的编写,因此本书内容看起来较为简单,如果你有幸看到这篇文章,我推荐的是你在系统学习完嵌入式在内核上开发的相关知识后再阅读此书,此书不适合作为启蒙书,更偏向与知识的梳理巩固和延伸。

模块化驱动程序的三个简单命令:驱动加载命令:insmod和modprobe,驱动卸载命令:rmmod。

指定模块的初始化和清理函数的宏定义:#include <linux/init.h>
module_init(init_function);

module_exit(cleanup_function);

三个常见的头文件:#include <linux/sched.h>:最重要的头文件中的一个,这个文件包含很多驱动使用的内核API的定义,包括睡眠函数和许多变量声明。

#include <linux/module.h>:必需的头文件,它必须在一个模块源码中包含。

#include <linux/version.h>:包含在建立的内核版本信息。

内核源码中重要的结构体:struct task_struct *current表示当前进程,current->pid 进程ID,current->comm 当前进程的命令名,该结构体定义在<linux/sched.h>中。

编写驱动程序时可以放置以下几个常见文档:MODULE_AUTHOR(author);

MODULE_DESCRIPTION(description);

MODULE_VERISON(version_string);

MODULE_DEVICE_TABLE(table_info);

MODULE_ALIAS(alternate_name);

MODULE_LICENSE("GPL");这个是内核认识的特定许可证,必须,防止各种内核报错。

vermagic.o:来自内核原码目录的目标文件,描述一个模块与之建立的环境。

/proc/modules和/sys/module :可以通过cat命令获取目录下当前加载模块的信息。

内核API中双下划线_ _的函数为低层的接口组件,应当小心使用。




 

原创粉丝点击