⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动程序笔记.txt

📁 Linux设备驱动程序笔记
💻 TXT
📖 第 1 页 / 共 5 页
字号:
linux设备驱动程序笔记.chm
Linux设备驱动程序(1)Hello, world!模块
学习心得
实验程序
实验结果
Linux设备驱动程序(2)-字符设备驱动程序
主设备号和此设备号
一些重要的数据结构
字符设备的注册
scull模型的内存使用
open和release
read和write
7模块实验
Linux设备驱动程序(3)-调试技术
内核中的调试支持
通过打印调试
通过查询调试
源码实验
Linux设备驱动程序(4)-并发和竞态
并发及其管理
信号量和互斥体
在scull中使用信号量
读取者/写入者信号量
Completion
自旋锁
锁陷阱
锁之外的办法
开发板实验
Linux设备驱动程序(4-补)-Linux中的循环缓冲区
缓冲区结构
ARM9开发板实验
Linux设备驱动程序(6)-高级字符驱动程序操作1
ioctl
选择ioctl命令
返回值
预定义命令
使用ioctl参数
权能与受限操作
定位设备(llseek实现)
ioctl和llseek实验。
Linux设备驱动程序(7)-高级字符驱动程序操作2
休眠
简单休眠(其实是高级休眠的宏)
阻塞和非阻塞操作
高级休眠
手工休眠
独占等待
唤醒的相关函数
poll 和 select
与read 和write 的交互
刷新待处理输出
底层数据结构
异步通知
scullpipe的实验(poll和fasync方法的实现):
Linux设备驱动程序(8)-高级字符驱动程序操作3
独享设备
单用户访问
阻塞型单用户访问
在 open 时复制设备
Linux设备驱动程序(9)-内核的数据类型
标准 C 语言类型
确定大小的类型
接口特定的类型(_t 类型)
其他移植性问题
时间间隔
页大小
数据对齐
指针和错误值
链表
ARM9实验板实验
datasize实验
kdatasize模块实验
kdataalign模块实验
Linux设备驱动程序(10)-分配内存
kmalloc 函数内幕
size 参数
flags 参数
后备高速缓存
内存池
get_free_page 和相关函数
alloc_pages 接口
vmalloc 和 ioremap
per-CPU 的变量
获得大的缓冲区
ARM9开发板实验
Linux设备驱动程序学习(11)-与硬件通信
I/O 端口和 I/O 内存
I/O 寄存器和常规内存
3使用 I/O 端口
I/O 端口分配
操作 I/O 端口
在用户空间访问 I/O 端口
串操作
暂停式 I/O
平台相关性
4使用 I/O 内存
I/O 内存分配和映射
访问I/O 内存
像 I/O 内存一样使用端口
ARM9的linux驱动接口
Linux设备驱动程序学习(12)-时间、延迟及延缓操作
度量时间差
使用 jiffies 计数器
处理器特定的寄存器
获取当前时间
延迟执行
长延迟
短延迟
内核定时器
定时器 API
内核定时器的实现
Tasklets
6工作队列
共享队列
ARM9 s3c2440AL 实验
Linux设备驱动程序学习(13)-中断处理
安装中断处理例程
快速和慢速处理例程
x86中断处理内幕
/proc 接口
自动检测 IRQ 号
处理例程的参数及返回值
实现中断处理例程
启用和禁止中断
顶半部和底半部
中断共享
中断驱动的 I/O
ARM9开发板实验
Linux设备驱动程序学习(14)-Linux设备模型
Kobject、Kset 和 Subsystem
Kobjects
kobject 初始化
对引用计数的操作
release 函数和 kobject 类型
kobject 层次结构、kset和子系统
kset
kset 上的操作
子系统
1底层sysfs操作
默认属性
非默认属性
二进制属性
符号链接
Linux设备驱动程序学习(15)-Linux设备模型
总线
总线的注册和删除
总线方法
对设备和驱动的迭代
总线属性
设备
设备注册
设备属性
设备结构的嵌入
设备驱动程序
驱动程序结构的嵌入
类 子系统
管理类的接口
类设备
类接口
Linux设备驱动程序学习(16)-Linux设备模型
lddbus模块:添加总线、导出总线设备和设备驱动的注册函数。
sculld模块:在scull的基础上添加设备和驱动注册和注销函数。
分析设备和驱动注册和注销核心函数,了解一般的注册、注销过程。
设备的注册
设备的注销
驱动程序的注册
驱动程序的注销
ARM9开发板实验
Linux设备驱动程序学习(15)-Linux设备模型
1热插拔
热插拔工具
mdev
mdev原理及bug
mdev使用
firmware
内核固件接口
固件接口工作原理
ARM9开发板实验


--------------------------------------------------------------------------------
嵌入式linux中文站 


Linux设备驱动程序(1)Hello, world!模块
 

一个学习Linux设备驱动程序都会碰到的第一个例程:

#include <linux/init.h>
#include <linux/module.h> 
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
    printk(KERN_ALERT "Hello, Tekkaman Ninja !\n");
    return 0;
}
static void hello_exit(void)
{
    printk(KERN_ALERT "Goodbye, Tekkaman Ninja !\n Love Linux !Love ARM ! Love KeKe !\n");
}
module_init(hello_init);
module_exit(hello_exit);
 


将其复制到工作目录,并编写了一个简单的Makefile文件:

KERNELDIR = /home/tekkaman/working/SBC2440/linux-2.6.22.2
    # The current directory is passed to sub-makes as argument
PWD := $(shell pwd)
INSTALLDIR = /home/tekkaman/working/rootfs/lib/modules
CROSS_COMPILE    =/home/tekkaman/working/crosstool-gcc410-k26222/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-
CC    = $(CROSS_COMPILE)gcc
obj-m := hello.o 
modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
    cp hello.ko $(INSTALLDIR)
clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
 


说实话,以上是参考了《Linux设备驱动程序(第3版)》的Makefile源码修改得来的。对Makefile不是很了解,是该好好学习学习了!

然后就是make  modules 、 make  modules_install 。

[root@Tekkaman-Ninja Helloworld]# make modules
make -C /home/tekkaman/working/SBC2440/linux-2.6.22.2 M=/home/tekkaman/working/Linuxdriver/Helloworld modules
make[1]: Entering directory `/home/tekkaman/working/SBC2440/linux-2.6.22.2'
  CC [M]  /home/tekkaman/working/Linuxdriver/Helloworld/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/tekkaman/working/Linuxdriver/Helloworld/hello.mod.o
  LD [M]  /home/tekkaman/working/Linuxdriver/Helloworld/hello.ko
make[1]: Leaving directory `/home/tekkaman/working/SBC2440/linux-2.6.22.2'


[root@Tekkaman-Ninja Helloworld]# make modules_install
cp hello.ko /home/tekkaman/working/rootfs/lib/modules


[root@Tekkaman-Ninja Helloworld]# 
 


在开发板上的操作:

[Tekkaman2440@SBC2440V4]#cd /lib/modules/

[Tekkaman2440@SBC2440V4]#ls

cs89x0.ko hello.ko p80211.ko prism2_usb.ko 

[Tekkaman2440@SBC2440V4]#insmod hello.ko 

Hello, Tekkaman Ninja !

[Tekkaman2440@SBC2440V4]#lsmod 

Module Size Used by Not tainted 

hello 1376 0 

[Tekkaman2440@SBC2440V4]#rmmod hello 

Goodbye, Tekkaman Ninja !

Love Linux !Love ARM ! Love KeKe ! 

[Tekkaman2440@SBC2440V4]#lsmod 

Module Size Used by Not tainted 

[Tekkaman2440@SBC2440V4]# 
 

 


--------------------------------------------------------------------------------
学习心得
(1)驱动模块运行在内核空间,运行时不能依赖于任何函数库和模块连接,所以在写驱动时所调用的函数只能是作为内核一部分的函数。
(2)驱动模块和应用程序的一个重要不同是:应用程序退出时可不管资源释放或者其他的清除工作,但模块的退出函数必须仔细撤销初始化函数所作的一切,否则,在系统重新引导之前某些东西就会残留在系统中。
(3)处理器的多种工作模式(级别)其实就是为了操作系统的用户空间和内核空间设计的。在Unix类的操作系统中只用到了两个级别:最高和最低级别。
(4)要十分注意驱动程序的并发处理。
(5)内核API中具有双下划线(_ _)的函数,通常是接口的底层组件,应慎用。
(6)内核代码不能实现浮点书运算。

(7)Makefile文件分析:
obj-m := hello.o  代表了我们要构造的模块名为hell.ko,make 会在该目录下自动找到hell.c文件进行编译。如果 hello.o是由其他的源文件生成(比如file1.c和file2.c)的,则在下面加上(注意红色字体的对应关系):
hello-objs := file1.o file2.o ......

    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
其中 -C $(KERNELDIR) 指定了内核源代码的位置,其中保存有内核的顶层makefile文件。
    M=$(PWD) 指定了模块源代码的位置
    modules目标指向obj-m变量中设定的模块。

(8)insmod使用公共内核符号表来解析模块中未定义的符号。公共内核符号表中包含了所有的全局内核项(即函数和变量的地址),这是实现模块化驱动程序所必须的。


(9)Linux使用模块层叠技术,我们可以将模块划分为多个层,通过简化每个层可缩短开发周期。如果一个模块需要向其他模块到处符号,则使用下面的宏:

EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
 

符号必须在模块文件的全局变量部分导出,因为这两个宏将被扩展为一个特殊变量的声明,而该变量必须是全局的。

(10)所有模块代码中都包含一下两个头文件:

#include <linux/init.h>
#include <linux/module.h> 
 


(11)所有模块代码都应该指定所使用的许可证:

MODULE_LICENSE("Dual BSD/GPL");
 


此外还有可选的其他描述性定义:

MODULE_AUTHOR("");
MODULE_DESCRIPTION("");
MODULE_VERSION("");
MODULE_ALIAS("");
MODULE_DEVICE_TABLE("");
 


上述MODULE_声明习惯上放在文件最后。

(12)初始化和关闭
初始化的实际定义通常如下:

static int _ _init initialization_function(void)
{
/*初始化代码*/
}
module_init(initialization_function)
 


清除函数的实际定义通常如下:

static int _ _exit cleanup_function(void)
{
/*清除代码*/
}
module_exit(cleanup_function)
 


(13) Linux内核模块的初始化出错处理一般使用“goto”语句。通常情况下很少使用“goto”,但在出错处理是(可能是唯一的情况),它却非常有用。在大二学习C语言时,老师就建议不要使用“goto”,并说很少会用到。在这里也是碰到的第一个建议使用“goto”的地方。“在追求效率的代码中使用goto语句仍是最好的错误恢复机制。”--《Linux设备驱动程序(第3版)》以下是初始化出错处理的推荐代码示例:

struct something *item1;
struct somethingelse *item2;
int stuff_ok;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -