随笔分类 - Linux驱动编程
摘要:ioctl 除了读取和写入设备之外,大部分驱动程序还需要另外一种能力,即通过设备驱动程序执行各种类型的硬件控制,通常这种需求使用ioctl方法支持,该方法实现了同名的系统调用; 在用户空间,ioctl系统调用的原型如下: 1 int ioctl(int d, int request, ...); 原
阅读全文
摘要:读取-复制-更新(read-copy-update,RCU)是一种高级的互斥机制,在正确的条件下,可以获得高的性能; RCU对它保护的数据结构做了一些限定,它针对经常发生读而很少发生写的情况做了优化,被保护的资源应该通过指针访问,而对这些资源的引用必须仅由原子代码拥有,在RCU保护的代码范围内不能进
阅读全文
摘要:当要保护的资源很小,很简单,会频繁的被访问而且写入访问很少的且必须快速时(即读不允许让写饥饿),就可以使用顺序锁(seqlock);从本质上讲,顺序锁会允许读取者对资源的自由访问,但需要读取者检查是否和写入者发生冲突,当这种冲突发生时,就需要重试对资源的访问; 顺序锁通常不能用于保护包含指针的数据结
阅读全文
摘要:原子整数操作 当共享资源是一个简单的整数值时,可以使用内核提供的一种原子的整数类型,称为atomic_t,定义在<linux/types.h>中,操作定义在<linux/atomic.h>中; 原子位操作 内核提供了一组针对原子位进行操作的函数,它们与体系结构相关,定义在文件<asm/bitops.
阅读全文
摘要:概念 自旋锁可以再不能休眠的代码中使用,比如中断处理例程;在正确使用的情况下,自旋锁通常可以提供比信号量更高的性能; 一个自旋锁是一个互斥设备,它只能由两个值,锁定和解锁;通常实现为某个整数值中的单个位;希望获得特定锁的代码测试相关位,如果锁可用,则锁定位被设置,而嗲吗继续进入临界区;相反,如果锁被
阅读全文
摘要:内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束;这个活动可能是,创建一个新的内核线程或者新的用户空间进程、对一个已有进程的某个请求,或者某种类型的硬件动作等; 内核提供了完成量(completion)来完成上述需求;完成量是一个轻量级的机制,它允许一个线程告诉另一个线
阅读全文
摘要:概念 一个信号量本质是一个整数值,它和一堆函数联合使用,这一对函数通常称为P和V;希望进入临界区的进程将在相关信号量上调用P;如果信号量的值大于零,则该值会减少1,进程可以继续执行;相反,如果信号量的值为0或者更小,则进程必须等待知道其他人释放该信号量;对信号量的解锁通过调用V完成;该函数增加信号量
阅读全文
摘要:竞态产生 Linux系统找那个存在大量的并发联系,因此会导致可能的竞态; 1. 正在运行的用户空间进程可以以多种组合方式访问我们的代码; 2. SMP系统甚至可以再不同的处理器上同时执行我们的代码; 3. 内核代码是可抢占的,因此,我们的驱动程序代码可能在任何时候丢失对处理器的独占,而拥有处理器的进
阅读全文
摘要:read和write原型 read和write方法完成的任务是相似的,亦即,拷贝数据到应用程序空间,或者反过来从应用程序空间拷贝数据;因此,它们的原型很相似,如下: 1 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
阅读全文
摘要:open方法 open方法提供给驱动程序以初始化的能力,在大部分驱动程序汇总,open应该完成以下工作: 1. 检查特定设备的错误,如设备为准备就绪或者硬件问题; 2. 如果设备是首次打开,则对其进行初始化; 3. 如有必要,更新f_op指针; 4. 分配并填写置于filp->private_dat
阅读全文
摘要:内核内部使用struct cdev结构来标识字符设备,在内核调用设备的操作之前,必须分配并注册一个或者多个上述结构,为此,我们的代码需要包含<linux/cdev.h>,其中定义了这个结构以及相关的辅助函数; 分配和初始化 分配和初始化上述结构的方式分为两种: 1. 如果打算在运行的时候获取一个独立
阅读全文
摘要:文件对象 文件对象是进程已经打开文件描述符的内存中的表示,单个文件可能有多个表示打开文件描述符的file结构; 1 struct file { 2 union { 3 struct llist_node fu_llist; /* 文件对象链表 */ 4 struct rcu_head fu_rcuh
阅读全文
摘要:主设备号和次设备号 对字符设备的访问是通过文件系统内的设备名称进行的,这些名称被称为特殊文件、设备文件、或者简单称之为文件系统树的节点,它们通常位于/dev目录。字符设备驱动程序的设备文件可以通过ls -l命令输出的第一列中的c字符来识别,块设备也出现在/dev下,但它们由字符b来标识; 通过执行l
阅读全文
摘要:模块支持参数的方法 内核允许驱动程序指定参数,这些参数可在运行insmod或者modprobe命令装载模块时赋值,modprobe还可以从它的配置文件(/etc/modporb.conf)中读取参数值; insmod加载模块时指定参数的方式如下: 1 insmod hellop howmany=10
阅读全文
摘要:insmod使用公共内核符号表来解析模块中未定义的符号。功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的。当模块装载到内核后,它所导出的任何符号都会变成内核符号表的一部分。通常情况下,模块只需要实现自己的功能,无需导出任何符号,但是如果其他模块想要使用该模块的
阅读全文
摘要:前置说明 本文例子中涉及两个模块hello.ko和world.ko,其中hello导出符号供world使用; insmod 该命令将模块的代码和数据装入内核,然后使用内核的符号表继续模块中任何未解析的符号。insmod不会修改模块的磁盘文件,而仅仅修改内存中的副本。insmod可以接受一些命令行选项
阅读全文
摘要:典型的模块Makefile如下所示; 1 ifneq ($(KERNELRELEASE),) 2 obj-m := hello.o 3 else 4 KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 PWD :=$(shell pwd) 6 def
阅读全文
摘要:netlink的特点 netlink提供了一种在用户态和内核态之间进行数据传递的方式; (1) 是一种异步的通信机制,传递的数据会放在socket的缓存队列中; (2) 内核可以主动发送数据给用户空间; (3) 能够在内核模块中使用; (4) 支持组播; (5) 使用套接字编程; 测试例程 用户态例
阅读全文

浙公网安备 33010602011771号