![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux设备驱动程序学习笔记
文章平均质量分 73
ljp827
这个作者很懒,什么都没留下…
展开
-
第二章:构造和允许模块(part1)
注:这是当初学习《linux设备驱动程序》的学习笔记,只有提纲挈领的作用,不足之处还请大家多多包涵,多多指点。Hello world模块模块能够调用printk是因为在insmod函数装入模块之后,模块就连接到了内核,可以访问内核的公用符号。printk( KERN_ALERT” Hello world.\n”);优先级只是一个字符串,如,该字符串置于printk格式字符串的前面。原创 2012-03-29 11:09:50 · 317 阅读 · 0 评论 -
第十二章:PCI驱动程序
PCI:peripheral component interconnect外围设备互联。PCI接口时钟频率一般是25MHz或者33MHz,最新的实现达到了66MHz甚至133MHz,配备32位数据总线。PCI寻址每一个PCI设备由一个总线编号、一个设备编号及一个功能编号来标识。PCI规范允许单个系统拥有高达256个总线,每个总线可以支持32个设备,每个设备最多有八种功能。每种功原创 2012-03-30 14:35:10 · 552 阅读 · 0 评论 -
第七章:时间、延迟及延缓操作
度量时间差HZ:每秒钟发生的时钟中断数。每次当时钟中断发生时,内核内部计数器的值加一。计数器是jiffies_64,无论在32位操作系统上还是在64位操作系统上,它都是一个64位的变量,并且是只读变量。使用jiffies计数器函数及变量声明在中,但此文件包含于中。jiffies_64被声明为volatile型,避免编译器对访问该变量的语句进行优化。比较时间先后的函数有:原创 2012-03-30 11:26:08 · 485 阅读 · 0 评论 -
第六章:高级字符驱动程序操作
ioctl大多数ioctl的实现中都包括一个switch语句来根据cmd参数选择对应的操作。用户空间,ioctl原型如下:int ioctl(int fd, unsigned long cmd, …);最后省略号一般表示可变参数,但在实际系统中,系统调用不会真正的使用可变数目的参数。它只是为了在编译时防止编译器进行类型检查。因为有时它是一个整形数,有时是一个指针。驱动程序的io原创 2012-03-30 10:58:56 · 334 阅读 · 0 评论 -
第五章:并发与竞态
竞态通常作为对资源的共享访问结果而产生。linux信号量的实现内核代码首先需要包括头文件。相关的类型是struct semaphore;直接创建并初始化信号的函数:void sema_init(struct semaphore *sem, int val);val是赋予信号量的初始值。其他的宏有:DECLARE_MUTEX(name); //一个成为name的信号量变量原创 2012-03-30 10:44:52 · 373 阅读 · 0 评论 -
第十一章:内核的数据处理
在编译时使用-Wall –Wstrict-prototypes选项编译可以防止大多数的代码缺陷。使用标准C语言类型内核中的普通内存地址通常是unsigned long ,因为:至少在当前linux支持的所有平台上,指针和long整型的大小是一样的。为数据项分配确定的空间大小在中定义若干类型:u8, u16, u32, u64。使用新的编译器可以定义如下类型等等:uint8_t,原创 2012-03-30 14:33:45 · 245 阅读 · 0 评论 -
第八章:分配内存
kmalloc函数的内幕kmalloc分配物理内存连续的一块区域,而且不对所获取的空间清零。#include void *kmalloc(size_t size, int flags);标志存放在中。GFP_KERNEL:表示它的函数正代表某个进程执行系统调用,此标志是可休眠的,因此函数必须可以重入。GFP_ATOMIC:用在原子上下文调用中,不会休眠,这是kmalloc甚原创 2012-03-30 14:30:51 · 334 阅读 · 0 评论 -
第三章:字符设备驱动程序
主设备号和次设备号对字符设备的访问是通过文件系统内的设备名称进行的,他们通常位于/dev目录,在此目录下ls –l 命令可以查看所有设备,每一行第一列”c”表示字符设备,”b”表示块设备。主设备号标识设备对应的驱动程序,虽然现代linux运行多个驱动程序共享主设备号,但是大多数设备依然按照“一个主设备号对应一个驱动程序”的原则组织。次设备号有内核使用,可以获得指向内核设备的一个指针。原创 2012-03-29 11:24:41 · 255 阅读 · 0 评论 -
第四章:调试技术
注:当初偷懒,本章内容不完整,详见书。通过使用printk函数调试printk打印信息拥有不同日志级别,这些表示日志级别的宏展开为一个字符串,所以使用此函数时,日志级别与打印信息之间没有逗号。printk采用的默认输出级别是定义在中的DEFAULT_MESSAGE_LOGLEVEL宏。当printk的优先级小于console_loglevel值时,消息才会被显示出来。如果系统同原创 2012-03-29 12:29:50 · 280 阅读 · 0 评论 -
第二章:构造和允许模块(part2)
内核符号表当模块被装入内核后,它所导出的任何符号都会变成内核符号表的一部分。模块层叠技术是一个常用的方案。modprobe是处理层叠模块的一个使用工具,它除了装入指定模块外还同时装入了指定模块所依赖的其他模块。(从当前目录装入自己的模块仍需要insmod,因为modprobe只能从标准的以安装模块目录中搜索需要装入的模块)如果一个模块需要向其他模块导出符号,则应该使用下面的宏:EX原创 2012-03-29 11:19:26 · 411 阅读 · 0 评论 -
第一章:设备驱动程序简介
注:这是当初学习《linux设备驱动程序》时记录的学习笔记,只有提纲挈领的作用,有不足之处还请大家多多指点。 可装载模块我们可以使用insmod程序将模块连接到正在运行的内核,也可以使用rmmod程序移除连接。设备和模块的分类Linux系统将设备分为三种类型:字符设备,块设备,网络接口。字符设备和块设备相同点:都可以通过文件系统节点来访问,比如/dev/tty1和/de原创 2012-03-29 10:57:30 · 273 阅读 · 0 评论 -
第九章:与硬件通信
I/0寄存器和常规内存I/0寄存器和RAM最主要区别:I/O操作具有边际效应,而内存操作则没有。使用I/O端口(I/O端口分配)#include struct resource *request_region(unsigned long first, unsigned long n, const char *name);该函数告诉内核,我们要使用起始于first的n个端口。na原创 2012-03-30 14:32:08 · 264 阅读 · 0 评论