Linux设备驱动程序
B!GGer.
97年程序员
展开
-
linux驱动44:与硬件通信(笔记)
linux驱动44:与硬件通信原创 2023-01-08 11:37:21 · 748 阅读 · 0 评论 -
linux驱动程序43:获取大的缓冲区
linux驱动程序43:获取大的缓冲区原创 2022-12-10 10:35:44 · 231 阅读 · 0 评论 -
linux驱动程序42:per-CPU变量
linux驱动程序42:per-CPU变量原创 2022-12-10 10:00:28 · 1242 阅读 · 0 评论 -
linux驱动程序41:vmalloc
linux驱动程序41:vmalloc原创 2022-11-25 09:26:09 · 307 阅读 · 0 评论 -
linux驱动程序40:页内存分配
linux驱动程序40:页内存分配原创 2022-11-19 10:02:52 · 395 阅读 · 1 评论 -
linux驱动39:内存池
linux驱动39:内存池原创 2022-11-12 10:06:10 · 529 阅读 · 0 评论 -
linux驱动38:后备高速缓存
后备高速缓存原创 2022-11-06 09:58:44 · 278 阅读 · 0 评论 -
linux驱动37:kmalloc内存分配
linux驱动37:kmalloc内存分配原创 2022-10-06 10:36:30 · 705 阅读 · 0 评论 -
linux驱动36:工作队列——共享队列
linux驱动36:工作队列——共享队列原创 2022-10-03 10:32:31 · 296 阅读 · 0 评论 -
linux驱动35:工作队列
linux驱动35:工作队列原创 2022-10-02 09:48:31 · 434 阅读 · 0 评论 -
linux驱动34:tasklet小任务机制
tasklet小任务机制原创 2022-09-12 10:27:24 · 404 阅读 · 0 评论 -
linux驱动33:内核定时器
内核定时器原创 2022-09-10 10:14:29 · 481 阅读 · 0 评论 -
linux驱动32:延迟执行
linux驱动32:延迟执行原创 2022-08-27 10:31:51 · 802 阅读 · 0 评论 -
linux驱动31:获取当前时间
获取当前时间原创 2022-08-20 09:58:25 · 627 阅读 · 0 评论 -
linux驱动30:度量时间差
jiffies计数器、计数寄存器原创 2022-08-14 10:51:07 · 243 阅读 · 0 评论 -
linux驱动29:访问控制
linux驱动:访问控制原创 2022-08-07 10:11:06 · 125 阅读 · 0 评论 -
linux驱动28:定位设备llseek
定位设备llseek原创 2022-07-30 09:21:58 · 436 阅读 · 0 评论 -
linux驱动27:异步通知
linux驱动异步通知原创 2022-07-23 09:58:03 · 182 阅读 · 0 评论 -
linux驱动26:poll和select
poll、select、epoll系统调用,功能本质上一样:允许进程决定是否可以对一个或多个打开的文件做非阻塞的读取和写入。原创 2022-07-09 09:38:36 · 285 阅读 · 0 评论 -
linux驱动25:阻塞型I/O
当数据不可用时,用户可能调用read,或缓冲区满了,用户调用write,在这些情况下,驱动程序应该阻塞该操作,将其置入休眠状态直到可以执行操作。原创 2022-06-26 10:35:26 · 126 阅读 · 0 评论 -
linux驱动24:ioctl
linux驱动ioctl原创 2022-06-05 11:23:46 · 353 阅读 · 0 评论 -
linux驱动23:并发与静态(除了锁之外的办法)
内核循环缓冲区(环形缓冲区):循环缓冲区是经常用于免锁的生产者/消费者任务的数据结构,适用于只有一个生产者和一个消费者的情况,如果是多个生产者或消费者时需要加锁。循环缓冲区在设备驱动程序中使用普遍。算法:一个生产者将数据放入数组的结尾,而消费者从数组的另一端移走数据。在达到数组尾部的时候,生产者绕回到数组的头部。因此,一个循环缓冲区需要一个数组以及两个索引值,一个用于下一个要写入新值的位置,而另一个用于下一个从缓冲区中移走值的位置。内核有一个通用的循环缓冲区实现,参阅<linux/kfif原创 2022-05-29 09:53:58 · 123 阅读 · 0 评论 -
linux驱动22:自旋锁spinlock
自旋锁:和信号量不同的是自旋锁可在不能休眠的代码中使用,如中断处理例程。在正确使用时,自旋锁通常比信号量具有更高的性能。如果锁可用,则锁定位被设置,代码继续进入临界区;相反则代码进入忙循环并重复检查锁,直到该锁可用。所有自旋锁在本质上是不可中断的,一旦调用了spin_lock,在获得锁之前一直处于自旋状态。自旋锁的实现由于linux所支持的架构不同而不同。自旋锁的核心规则是:任何拥有自旋锁的代码必须是原子的。自旋锁不能休眠。自旋锁必须在可能的最短时间内拥有。头文件:<lin原创 2022-05-22 10:50:47 · 962 阅读 · 0 评论 -
linux驱动21:内核创建类class_create
利用mknod命令手动创建设备节点不方便,Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。#include <linux/init.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kdev_t.h>#include <linux/fs.h>#include &l原创 2022-05-22 09:35:40 · 523 阅读 · 0 评论 -
linux驱动20:completion(用于同步)
completion是一种轻量级同步机制,允许一个线程通知另外一个线程某个工作已经完成。头文件:<linux/completion.h>初始化:init_completion(struct completion *c);等待完成:void wait_for_completion(struct completion *c);执行一个非中断的等待,如果代码调用了该函数且没有人调用completion,将产生一个不可杀进程。触发完成:void completion(st原创 2022-05-14 09:54:36 · 195 阅读 · 0 评论 -
linux驱动19:读取者/写入者信号量
rwsem(reader/writer semaphore),很少使用,一个rwsem可允许一个写入者或无限多个读取者拥有该信号量,写入者具有更高的优先级,适合在很少需要写访问且写入者只会短时间拥有信号量的时候使用。头文件:<linux/rwsem.h>数据类型:struct rw_semaphore初始化:void init_rwsem(struct rw_semaphore *sem);读者接口:void down_read(struct rw_semaphore *原创 2022-05-14 09:17:46 · 141 阅读 · 0 评论 -
linux驱动18:信号量(内核)
一个信号量本质上是一个整数值,它和一对函数联合使用,P(-1)和V(+1)。内核中的信号量通常用于互斥;用于互斥时,信号量的值初始化为1,用于同步时初始化为0。内核使用信号量包含<linux/semaphore.h>,相关的类型为struct semaphore。信号量初始化:void sema_init(struct semaphore *sem, int val);val:信号量的初始值P函数:int down(struct semaphore *sem);减..原创 2022-05-04 10:28:33 · 486 阅读 · 0 评论 -
linux驱动17:/proc文件系统(调试技术)
/proc文件系统是一种特殊的、由软件创建的文件系统,内核使用它向外界导出信息。/proc下面的每个文件都绑定于一个内核函数,用户读取其中的文件时,该函数动态地生成文件的“内容”。/proc文件支持读写,大多数情况下/proc文件是只读的。使用时包含<linux/proc_fs.h>。seq_file接口为大的内核虚拟文件提供一组简单的函数。使用时包含<linux/seq_file.h>,必须建立四个迭代器。start、next、show、stop(顺序操作,四个迭代器)原创 2022-04-17 11:35:13 · 1220 阅读 · 0 评论 -
linux驱动16:read和write
linux驱动程序read和write原创 2022-03-27 10:19:35 · 957 阅读 · 0 评论 -
linux驱动15:open和release
o驱动程序pen和release原创 2022-03-19 09:50:31 · 2083 阅读 · 0 评论 -
linux驱动14:字符设备的注册
字符设备的注册原创 2022-03-13 10:57:23 · 631 阅读 · 0 评论 -
linux驱动13:重要的数据结构
驱动程序重要数据结构原创 2022-03-06 11:04:23 · 313 阅读 · 0 评论 -
linux驱动12:主设备号和次设备号
主设备号和次设备号原创 2022-02-27 16:19:29 · 2422 阅读 · 0 评论 -
linux驱动11:模块参数
模块参数可以在运行insmod或modprobe命令装载模块时赋值,modprobe可以从配置文件(/etc/modprobe.conf)中读取参数值。在insmod改变模块参数之前,模块必须让参数对insmod命令可见。参数使用 module_param(变量名,类型,访问许可值) 宏来声明,在源文件头部声明参数。所有的模块参数都应该在源文件中给定一个默认值。模块支持的模块参数:bool、invbool(取反,true变为false,false变为true)charp(字符指针)...原创 2022-02-20 10:42:05 · 800 阅读 · 0 评论 -
linux驱动10:初始化和关闭
初始化static int __init initialization_function(void){ /*初始化代码*/}module_init(initialization_function);初始化函数应该声明为static__init表明仅在初始化期间使用,__init和__initdata是可选的module_init的使用是强制性的,调用初始化函数关闭static void __exit cleanup_function(void){ /*清原创 2022-02-19 11:00:51 · 324 阅读 · 0 评论 -
linux驱动09:预备知识
所有模块都包含:#include <linux/module.h>#include <linnux/init.h>大部分包含:#include <module/param.h>文件最后:MODULE_LICENSE("GPL"); #许可证,必须MODULE_AUTHOR(""); #作者MODULE_DESCRIPTION(""); #描述模块用途MODULE_VERSION(""); #代码修订号MODULE_ALIAS("")原创 2022-02-19 10:25:43 · 225 阅读 · 0 评论 -
linux驱动08:内核符号表
insmod使用公共内核符号表来解析模块中未定义的符号。公共内核符号表中包含了所有的全局内核项(即函数和变量)的地址,这是实现模块化驱动程序所必须的。模块层叠技术:新模块可以使用由我们自己的模块导出的符号,这样我们可以在其他模块上层叠新的模块。一个模块需要向其他模块导出符号,使用以下宏:EXPORT_SYMBOL(name);EXPORT_SYMBOL_GPL(name); #导出的模块只能被GPL许可证下的模块使用符号必须在模块文件的全局部分导出,不能在函数中导出,因为以上宏被扩展原创 2022-02-13 15:59:19 · 322 阅读 · 0 评论 -
linux驱动07:核心模块与应用程序的对比
图1 将模块链接到内核内核编程和应用程序编程一点重要的不同之处在于各环境下处理错误的方式不同。通常将运行模式称为内核空间和用户空间,两种模式具有不同的优先权等级,也有自己的内存映射(地址空间)。模块运行在内核空间,用于扩展内核功能,应用程序运行在用户空间,实现用户定义的功能。Unix中,内核运行在最高级别(超级用户态),可以进行所有操作;应用程序运行在最低级别(用户态),处理器控制着对硬件的访问以及对内存的非授权访问。一个驱动程序要执行两类任务:模块中的某些函数作为系统调用的一部分而执行..原创 2022-01-16 10:23:47 · 513 阅读 · 0 评论 -
linux驱动06:hello world 模块
#include <linux/init.h>#include <linux/module.h>static int hello_init(void){ printk(KERN_ALERT"hello world!\n"); return 0;}static void hello_exit(void){ printk(KERN_ALERT"goodbye world!\n");}MODULE_LICENSE("GPL");module_init(hel.原创 2022-01-16 09:24:39 · 511 阅读 · 0 评论 -
linux驱动05:编译与装载
一、编译Makefile#如果已定义KERNELRELEASE,则说明是从内核构造系统调用的,因此可利用其内建语句。ifneq ($(KERNELRELEASE),)obj-m := hello.o#否则是直接从命令行调用的,这时要调用内核构造系统。elseKDIR := /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)all: make -C $(KDIR) M=$(PWD) modulesclean: rm原创 2022-01-09 15:25:29 · 300 阅读 · 0 评论