【原创】《Linux设备驱动程序》学习之初探驱动 --- 驱动模块简介


【原创】《Linux设备驱动程序》学习之初探驱动 --- 驱动模块简介


前段时间学习了《Linux内核设计与实现》第三版,是基于Linux2.6.10讲解的,对Linux内核有了大概了解,今天开始学习《Linux设备驱动程序》第三版,此后将对学习过程中必要的知识点做个记录。

  Linux2.6.10源码下载地址 https://www.kernel.org/pub/linux/kernel/ ,在子目录v2.6下找。

《Linux设备驱动程序》第三版 示例源码下载地址 ftp://ar.linux.it/pub/,子目录ldd3即是第三版的示例代码。


第一章 --- 设备驱动程序简介

驱动程序的作用在于提供机制而不是提供策略。区分机制和策略师UNIX设计背后隐藏的最好思想之一。

机制 --- 需要提供什么功能;策略 --- 如何使用这些功能。即,驱动程序应该处理如何使硬件可用的问题,而将怎样使用硬件的问题留给上层应用程序。实际上,不带策略是软件设计者的一个共同目标。

内核功能划分:进程管理;内存管理;文件系统;设备控制;网络功能。

Linux有一个很好的特性:内核提供的特性可在运行时进行扩展。

Linux系统将设备分为三种基本类型:字符设备;块设备;网络设备。


第二章 --- 构造和运行模块

模块运行在所谓的内核空间里,而应用程序运行在所谓的用户空间中,这个概念是操作系统理论的基础之一。

内核编程区别于常见的应用程序编程的地方在于对并发的处理。时刻要铭记:同一时刻,可能会有许多事情正在发生。

Linux内核代码(包括驱动程序代码)必须是可重入的,必须能够同时运行在多个上下文。

驱动程序编写人员所犯的一个常见错误是:认为只要某段代码没有进入睡眠状态(或者阻塞),就不会产生并发问题。

内核代码不能实现浮点数运算,内核代码中也不需要浮点运算。

模块代码必须始终检查返回值,并确保所请求的操作已真正成功。


第二章 --- 快速参考

本节总结了我们在本章接触到的内核函数, 变量, 宏定义, 和 /proc 文件. 它
的用意是作为一个参考. 每一项列都在相关头文件的后面, 如果有. 从这里开始, 
在几乎每章的结尾会有类似一节, 总结一章中介绍的新符号. 本节中的项通常以
在本章中出现的顺序排列:  
insmod 
modprobe 
rmmod  
用户空间工具, 加载模块到运行中的内核以及去除它们. 
#include <linux/init.h> 
module_init(init_function); 
module_exit(cleanup_function); 
指定模块的初始化和清理函数的宏定义. 
__init 
__initdata 
__exit 
__exitdata  
函数( __init 和 __exit )和数据 (__initdata 和 __exitdata)的标记, 
只用在模块初始化或者清理时间. 为初始化所标识的项可能会在初始化完
成后丢弃; 退出的项可能被丢弃如果内核没有配置模块卸载. 这些标记通
过使相关的目标在可执行文件的特定的 ELF 节里被替换来工作. 
#include <linux/sched.h> 
最重要的头文件中的一个. 这个文件包含很多驱动使用的内核 API 的定
义, 包括睡眠函数和许多变量声明. 
struct task_struct *current; 
当前进程. 
current->pid 
current->comm  
进程 ID 和 当前进程的命令名.

obj-m  
一个 makefile 符号, 内核建立系统用来决定当前目录下的哪个模块应当
被建立. 
/sys/module  
/proc/modules  
/sys/module 是一个 sysfs 目录层次, 包含当前加载模块的信息. 
/proc/moudles 是旧式的, 那种信息的单个文件版本. 其中的条目包含了
模块名, 每个模块占用的内存数量, 以及使用计数. 另外的字串追加到每
行的末尾来指定标志, 对这个模块当前是活动的. 
vermagic.o  
来自内核源码目录的目标文件, 描述一个模块为之建立的环境. 
#include <linux/module.h> 
必需的头文件. 它必须在一个模块源码中包含. 
#include <linux/version.h> 
头文件, 包含在建立的内核版本信息. 
LINUX_VERSION_CODE 
整型宏定义, 对 #ifdef 版本依赖有用. 
EXPORT_SYMBOL (symbol); 
EXPORT_SYMBOL_GPL (symbol); 
宏定义, 用来输出一个符号给内核. 第 2 种形式输出没有版本信息, 第 
3 种限制输出给 GPL 许可的模块. 
MODULE_AUTHOR(author); 
MODULE_DESCRIPTION(description); 
MODULE_VERSION(version_string); 
MODULE_DEVICE_TABLE(table_info); 
MODULE_ALIAS(alternate_name); 
放置文档在目标文件的模块中. 
module_init(init_function); 
module_exit(exit_function);

宏定义, 声明一个模块的初始化和清理函数. 
#include <linux/moduleparam.h> 
module_param(variable, type, perm); 
宏定义, 创建模块参数, 可以被用户在模块加载时调整( 或者在启动时间, 
对于内嵌代码). 类型可以是 bool, charp, int, invbool, short, ushort, 
uint, ulong, 或者 intarray. 
#include <linux/kernel.h> 
int printk(const char * fmt, ...); 
内核代码的 printf 类似物. 


原文链接 http://blog.csdn.net/geng823/article/details/36905741


posted @ 2014-07-04 19:40  GengLUT  阅读(156)  评论(0编辑  收藏  举报