Linux 设备驱动开发
文章平均质量分 78
主要用于嵌入式开发工作者或者爱好者进行Linux设备驱动开发交流,这里大部分是自己学习Linux设备驱动开发中遇到的问题或者总结性文章,笔者在今后的工作中也将陆续添加在驱动开发中继续进行一些技术性总结,希望对大家的学习有所帮助。
狂奔的乌龟
1、博客介绍:专注分享ARM Trustzone/TEE/Linux/嵌入式等领域知识,大部分是个人学习笔记,关注我,一起学习!希望在这里能和大家一起进步,星光不负赶路人,加油!
2、个人介绍:ARM/TEE/Linux等领域忠实爱好者,个人长期专注于硬件安全、系统安全、嵌入式领域安全开发工作。
3、个人语录:积累是一个漫长的过程,未来很长,一起努力,只要路是对的,就不怕路远。
4、招聘广告:目前在国内大厂上班,长期招聘高级别&有经验的硬件安全、系统安全、嵌入式底层软件架构师&SE&MDE,寻求志同道合有志之士,有意向可私信我。
展开
-
Linux内核学习笔记——ACPI命名空间
所有定义块都加载到单个命名空间中。命名空间 是由名称和路径标识的对象层次结构。以下命名约定适用于 ACPI 中的对象名称 命名空间:所有名称的长度均为 32 位。名称的第一个字节必须是“A”-“Z”、“_”之一。名称的每个剩余字节必须是“A”-“Z”、“0”之一 - ‘9’, ‘_’.以“_”开头的名称由 ACPI 规范保留。“”符号表示命名空间的根(即名称 前缀为 ‘’ 是相对于命名空间根目录的)。“^”符号表示当前命名空间节点的父节点 (即以“^”开头的名称相对于 当前命名空间节点)。原创 2023-08-20 21:31:33 · 872 阅读 · 0 评论 -
Linux内核学习笔记——内核页表隔离KPTI机制
KPTI补丁基于KAISER,它是一个用于缓解不太重要问题的早期补丁,当时业界还未了解到Meltdown的存在。如果没有KPTI,每当执行用户空间代码(应用程序)时,Linux会在其分页表中保留整个内核内存的映射,并保护其访问。这样做的优点是当应用程序向内核发送系统调用或收到中断时,内核页表始终存在,可以避免绝大多数上下文切换相关的开销(TLB刷新、页表交换等)。KPTI通过完全分离用户空间与内核空间页表来解决页表泄露。支持进程上下文标识符(PCID)特性的x86处理器可以用它来避免TLB刷新,但即原创 2022-12-28 10:32:50 · 1176 阅读 · 0 评论 -
Linux内核学习笔记——Crypto基础框架
本篇文章主要分析关于kernel crypto算法框架,以及结合它在文件系统加密这一场景中的应用,分析内部的实现细节,以便读者对Linux crypto框架有相关的认识,并能基于它做开发。本篇文章的所有代码都是围绕Linux-5.10源码进行阅读。为方便理解,我们约定一些术语:数据转换(transformation/TFM):不管是对数据做加/解密,还是做hash,都定义成是对数据所做的转换操作。...原创 2022-07-11 00:15:00 · 3367 阅读 · 0 评论 -
一步一步学习 Linux 驱动之 platform 机制(tiny210 按键驱动)
1、platform device/*** @Author: ZP1015 ** @Copyright:SCUT.* * @Function:Platform device driver for button * * @Creat:2015-06-10** @Modify:2015-12-29**/#include <linux/kernel.h>#include <linu原创 2015-12-29 14:48:22 · 1148 阅读 · 0 评论 -
Linux 设备驱动常用函数解析(更新中)
1、MKDEVMKDEV(int major,int minor)/** * MKDEV() - 将主设备号和次设备号转换成dev_t类型(32位) * @major: 主设备号 * @minor: 次设备号 * Return value:dev_t类型 *//*函数实现*/#define MINORBITS 20#define MKDEV(ma,mi) (((ma) <<原创 2015-12-21 14:30:16 · 1941 阅读 · 0 评论 -
Linux MakeFile (编写、函数以及指定位置存放)
1、MakeFile 编写正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o dis原创 2015-12-16 17:03:59 · 4739 阅读 · 0 评论 -
Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)
本文将介绍网络连接建立的过程、收发包流程,以及其中应用层、tcp层、ip层、设备层和驱动层各层发挥的作用。原创 2015-08-11 21:56:10 · 4150 阅读 · 0 评论 -
open(“/dev/mem “,O_RDWR | O_SYNC)
【摘要】open(“/dev/mem”,O_RDWR|O_SYNC) 中/dev/mem是物理内存的全映像,可以用来访问物理内存。然后mmap,接着就可以用mmap的地址来访问物理内存,这实际上就是实现用户空间驱动的一种方法。 http://blog.csdn.net/wlp600/article/details/6893636#原创 2015-07-25 19:14:04 · 12459 阅读 · 2 评论 -
Linux 设备驱动之 DTS 描述的资源
在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内存地址等资源。这些资源的描述信息存放在 resource 数据结构中, 相同的资源存放在一个树形树形数据结构中, 通过父节点, 兄弟节点, 子节点相连。 比如中断资源, IO端口资源, IO内存资源,原创 2015-07-16 22:27:36 · 6423 阅读 · 0 评论 -
ARM Linux 3.x 的设备树(Device Tree)之DTB、DTS
1、ARM Device Tree起源Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”,引发ARM Linux社区的地震,随后ARM社区进行了一系列的重大修正。在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥转载 2015-07-16 22:19:38 · 7738 阅读 · 0 评论 -
Linux 驱动之并发控制 (信号量、原子锁和自旋锁)
摘要:并发控制,是多任务操作系统必须面临和解决的一个问题。并发与互斥,主要是用于保护临界资源,如果不站在操作系统进程调度的角度,就很难理解并发与互斥的概念和应用。无论是抢占式操作系统,还是分时操作系统,对于临界资源的保护,都必须采用互斥的机制。Linux内核中,有多种并发控制的机制:自旋锁、原子变量、信号量、读写锁等等。不同的并发机制对应于不同的应用场合,比如说,自旋锁可以应用到中断处理函数中,信号量则不可以。本文主要从一个globalmem_lock例子来阐述信号量的使用。注:该例子取自《Linux设备驱原创 2015-06-16 08:44:34 · 2769 阅读 · 0 评论 -
Linux 设备驱动开发目录
Linux 驱动,从最开始LED驱动开发到块设备,目前还在更新中~系统设备驱动,platform 机制,设备分层~原创 2015-06-15 21:22:13 · 1884 阅读 · 0 评论 -
Linux 设备模型(中)之上层容器
基本概念 总线 Linux设备模型是由总线(bus_type),设备(device),驱动(device_driver)这三个数据结构来描述的。总线是处理器和一个或多个设备之间的通道。在设备模型中, 所有的设备都通过总线相连, 甚至是内部的虚拟“platform”总线(下一篇介绍),注意,这里设备模型中只是为个更好方便管理,所以有些总线是pic,i2c,usb等,但都只是一转载 2015-06-15 21:19:10 · 794 阅读 · 0 评论 -
Linux 设备模型(上)之底层模型
以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添转载 2015-06-15 21:15:24 · 2000 阅读 · 0 评论 -
Linux 驱动之块设备结构体 (二)
上回最后面介绍了相关数据结构,下面再详细介绍块设备对象结构 block_device内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区。如果该结构代表一个分区,则其成员bd_part指向设备的分区结构。如果该结构代表设备,则其成员bd_disk指向设备的通用硬盘结构gendisk当用户打开块设备文件时,内核创建结构block_device实例,设备转载 2015-06-15 16:56:16 · 2173 阅读 · 1 评论 -
Linux 驱动之块设备 (卸载块模块就死机了,尚未解决) (一)
好了,这里我们假定你已经搞定上面的最简单的模块了,懂得什么是看模块,以及简单模块的编写、编译、加载和卸载。还有就是,什么是块设备,什么是块设备驱动,这个也请自行google吧,因为我们已经迫不及待要写完程序下课。为了建立一个可用的块设备,我们需要做......1件事情:1:用add_disk()函数向系统中添加这个块设备 添加一个全局的 static struct原创 2015-06-15 14:50:05 · 3109 阅读 · 0 评论 -
/dev、/sys/devices 和 /sys/dev 之间区别
/dev,设备文件存储目录,应用程序通过对这些文件的读写和控制,可以访问实际的设备;/sys/devices 目录,按照设备挂接的总线类型,组织成层次结构,保存了系统所有的设备;是文件系统管理设备的最重要的目录结构;这是内核设备按总线类型分层放置的目录结构, devices 中的所有设备都是连接于某种总线之下,在这里的每一种具体总线之下可以找到每一个具体设备的符号链接,它也是构成 Linux 统一设备模型的一部分;/sys/dev 下有两个子目录,block和char,存放的是块设备和字符设备的原创 2015-06-12 16:23:41 · 13380 阅读 · 0 评论 -
ARM 指令集
1、ARM指令集ADC带进位的32位数加法ADD32位数相加AND32位数的逻辑与B在32M空间内的相对跳转指令BEQ相等则跳转(Branch if EQual)BNE不相等则跳转(Branch if Not Equ原创 2015-06-10 15:23:00 · 898 阅读 · 0 评论 -
Linux 内核调试之 printk
问题描述:最近这两天再调试 platform 驱动,程序老是有点小问题,得不到自己想要的结果,突然意识到内核调试重要性,重新整理一下 printk 基本用法。内核通过 printk() 输出相关信息,在调用 printk() 函数时必须要指定日志级别。1、printk 日志等级在 include/linux/kernel.h 中定义了如下几个日志级别#define KERN_EMERG "<0>" /* 系统崩溃 */#define KERN_ALERT "<1>" /* 必须紧急处理 */原创 2015-06-09 20:15:07 · 2052 阅读 · 0 评论 -
Linux 设备模型之(总线、设备和驱动程序)(三)
总线设备驱动模型其实现主要是基于Kobject和sysfs等机制,对于驱动模型程序开发主要是理解三个元素:总线、设备、驱动的关系。三者之间因为一定的联系性实现对设备的控制。首先是总线,总线是三者联系起来的基础,通过一种总线类型,将设备和驱动联系起来。总线类型中的match函数用来匹配设备和驱动。当匹配操作晚餐之后就会控制驱动程序中的probe函数。总线设备驱动模型的设计主要包括三个元素的注册,将三个元素加载到内核中,然后通过内核的内部机制将三者联系起来。首先,总线类型的注册,包括属性文件的添加,总线原创 2015-06-08 20:20:46 · 2062 阅读 · 0 评论 -
Linux 设备模型之 (kobject、kset 和 Subsystem)(二)
问题描述:前文我们知道了/sys是包含内核和驱动的实施信息的,用户可以通过 /sys 这个接口,用户通过这个接口可以一览内核设备的全貌。本文将从Linux内核的角度来看一看这个设备模型是如何构建的。1、kobject 结构 在Linux内核里,kobject是组成Linux设备模型的基础,一个kobject对应sysfs里的一个目录。从面向对象的角度来说,kobject可以看作是所有设备对象的基类,因为C语言并没有面向对象的语法,所以一般是把kobject内嵌到其他结构体里来实现类似的作用,这里的其他原创 2015-06-08 15:17:49 · 2704 阅读 · 0 评论 -
Linux 设备模型基本概念 (一)
1、设备模型引入Linux 2.6内核最初为了应付电源管理的需要,提出了一个设备模型来管理所有的设备。在物理上,外设之间是有一种层次关系的,比如把一个U盘插到笔记本上,实际上这个U盘是接在一个USB Hub上,USB Hub又是接在USB 2.0 Host Controller (EHCI)上,最终EHCI又是一个挂在PCI Bus上的设备。这里的一个层次关系是:PCI->EHCI->USB Hub->USB Disk。如果操作系统要进入休眠状态,首先要逐层通知所有的外设进入休眠模式,然后整个系统才可以原创 2015-06-04 10:37:37 · 5548 阅读 · 1 评论 -
Linux 驱动之内核定时器
1、定时器 之前说过两类跟时间相关的内核结构。1、延时:通过忙等待或者睡眠机制实现延时。2、tasklet和工作队列,通过某种机制使工作推后执行,但不知道执行的具体时间。接下来要介绍的定时器,能够使工作在指定的时间点上执行,而且不需要使用忙等待这类的延时方法。通过定义一个定时器,告之内核在哪个时间需要执行什么函数就可以了,等时间一到,内核会就执行指定的函数。原创 2015-06-03 19:29:29 · 1576 阅读 · 0 评论 -
Linux 驱动之中断下半部之工作队列
1、工作队列的使用按惯例,在介绍工作队列如何实现之前,先说说如何使用工作队列实现下半部。步骤一、定义并初始化工作队列:创建工作队列函数:struct workqueue_struct *create_workqueue(const char *name)函数传参是内核中工作队列的名称,返回值是workqueue_struct结构体的指针,该结构体用来维护一个等待队列。我的代码如下: struct workqueue_struct * ZP1015_wq; //定义工作队列 ZP101原创 2015-06-03 15:45:21 · 3101 阅读 · 0 评论 -
Linux 驱动之内核空间分配内存
一、内核空间和用户空间有什么不同学c语言的时候应该学过,从用户空间看,每个进程都傻乎乎的以为自己有4G的内存空间,其中位于高地址(3G-4G)的1G空间给内核用,另外的3G(0-3G)都是它一个人独占的。所以用户空间很慷慨的把3G的空间分了好几个区域,如堆、栈、代码段等。其中,malloc()分配的空间位于堆,而程序中的自动变量,如你在函数内定义的“inti”,它是放在栈上,同时。用户原创 2015-05-29 10:18:25 · 2937 阅读 · 0 评论 -
Linux 驱动之 EXPORT_SYMBOL 函数以及 2.6 内核 Unknown symbol bug 解决办法
1、Linux中EXPORT_SYMBOL的用法 EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。您还可以手工修改内核源代码来导出另外的函数,用于重新编译并加载新内核后的测试。//mod1.c编译模块mod2,成功。加载mod2时,输出:insmod: error inserting 'mod2.ko': -1 Invalid parametersdmesg查看:mod2: no symbol version for func原创 2015-05-28 20:54:22 · 3229 阅读 · 0 评论 -
一步一步学习 Linux 驱动之(Kconfig、Makefile)
1、概述 在linux编写驱动的过程中,有两个文件是我们必须要了解和知晓的。这其中,一个是Kconfig文件,另外一个是Makefile文件。如果大家比较熟悉的话,那么肯定对内核编译需要的.config文件不陌生,在.config文件中,我们发现有的模块被编译进了内核,有的只是生成了一个module。首先我们来学习什么Makefile,什么是Kconfig ,什么是.config Makefile:一个文本形式的文件,其中包含一些规则告诉make编译哪些文件以及怎样编译这些文件。Kconfi原创 2015-05-28 11:23:27 · 2532 阅读 · 0 评论 -
tiny210 出现 nfs:server is not responding,still trying 原因与解决方案
#This line cannot be removed. by FriendlyARM(www.arm9.net)CheckOneButton=NoAction = InstallOS =LinuxLCD-Mode = NoLCD-Type = S70LowFormat = NoVerifyNandWrite = NoCheckCRC32=NoStatusType = Beeper | LED################### Linux ##############原创 2015-05-24 16:44:32 · 1322 阅读 · 0 评论 -
linux 驱动程序头文件
1、编写任何驱动程序都必须带的头文件#include <linux/module.h>:在编写任何模块都需要包含此头文件。该头文件自动包含了 <linux/version.h>头文件,该头文件包含了宏 MODULE_LICENSE("GPL")的定义。#include <linux/init.h>:此头文件也是原创 2015-05-19 16:00:07 · 3209 阅读 · 0 评论 -
mini2440_pwm.c 分析(PWM 驱动)
1、概述本驱动用定时器0产生PWM脉冲信号,GPB0管脚输出接蜂鸣器。mini2440共有5个定时器,不过只有Timer 0~4具有PWM功能2、驱动程序#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/interrup原创 2015-05-19 14:35:42 · 2621 阅读 · 0 评论 -
mini2440_adc.c 分析( ADC 驱动)
1、ADC硬件原理概述 我们从上面的结构图和数据手册可以知道,该ADC模块总共有8个通道可以进行模拟信号的输入,分别是AIN0、AIN1、AIN2、AIN3、YM、YP、XM、XP。那么ADC是怎么实现模拟信号到数字信号的转换呢?首先模拟信号从任一通道输入,然后设定寄存器中预分频器的值来确定AD转换器频率,最后ADC将模拟信号转换为数字信号保存到ADC数据寄存器0中(ADCDAT0),然后ADCDAT0中的数据可以通过中断或查询的方式来访问。对于ADC的各寄存器的操作和注意事项请参阅数据手册。原创 2015-05-19 10:00:40 · 2554 阅读 · 15 评论 -
linux platform 设备驱动之 match 自动匹配
struct platform_device { // linux/platform_device.h const char * name; int id; struct device dev; u32 num_resources; struct resource * resource; struct platform_device_id *id_entry; /* arch specific additions */ struct pdev_archdata archdata;原创 2015-05-13 21:54:59 · 3910 阅读 · 0 评论 -
一步一步学习 Linux 驱动之设备控制接口函数(ioctl 函数)
一、 什么是ioctl。ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:int ioctl(int fd, ind cmd, …);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那在用户空间, ioctl 系统调用有下面的原型:int ioctl(int fd, unsigned long cmd,原创 2015-05-06 20:57:28 · 6294 阅读 · 6 评论 -
一步一步学习 Linux 驱动之内核中断函数 request_irq
request_irq的作用是申请使用IRQ并注册中断处理程序。request_irq()函数的原型如下:/* kernel/irq/manage.c */int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqfl原创 2015-05-04 10:14:21 · 5968 阅读 · 0 评论 -
一步一步学习 Linux 驱动之自动创建设备节点
extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) __attribute__((format(printf, 5, 6)));函数功能: 函数device_create()用于动态的建立逻辑设备,并对新的逻辑设备类进行相应初始化,将其与函数的第一个参原创 2015-04-30 15:07:07 · 2607 阅读 · 1 评论 -
内核怎么通过主设备号找驱动、次设备号找设备
MAJOR宏将dev_t向右移动20位,得到主设备号;MINOR宏将dev_t的高12位清零,得到次设备号。相反,可以将主设备号和次设备号转换为设备号类型(dev_t),使用宏MKDEV可以完成这个功能。 Linux内核允许多个驱动共享一个主设备号,但更多的设备都遵循一个驱动对一个主设备号的原则。 内核维护着一个以主设备号为key的全局哈希表,而哈希表中数据部分则为与该主设备号设备对应的驱动程序(只有一个次设备)的指针或者多个同类设备驱动程序组成的数组的指针(设备共享主设备号)。根据所编写的驱动程序原创 2015-04-27 09:22:47 · 5345 阅读 · 2 评论 -
大端与小端
一、概念及详解 在各种体系的计算机中通常采用的字节存储机制主要有两种: big-endian和little-endian,即大端模式和小端模式。 先回顾两个关键词,MSB和LSB: MSB:Most Significant Bit ------- 最高有效位 LSB:Least Significant Bit ------- 最低有效位 大端模式(big-edian) big-endian:MSB存放在最低端的地址上。 举例,双字节数0x1234以big-原创 2015-04-21 11:08:33 · 1153 阅读 · 0 评论 -
驱动模块静态编译到 Linux 内核
一、准备好可以正常引导开发板的源码二、在内核源码kernel文件夹的driver目录下,创建led_arm文件夹 mkdir drivers/led_arm三、将“LED驱动实验”的驱动程序拷贝到led_arm目录下(详情见上一次LED驱动博客) 将led.c拷贝在该文件夹下面 ①添加一个Kconfig文件config MYLED tristate "MYLED" default n help this is a LED driver ②原创 2015-04-19 20:03:00 · 3903 阅读 · 0 评论 -
Telnet 在 mini2440 上的移植
mini2440 内核以及根文件系统分别是通过tftp、NF方式加载的,为了解决开发板串口不够用的问题,给开发板安装一个telnet是一个不错的解决方案,毕竟如果用超级终端是必须占用一个串口的。1.进入busybox源代码目录,选择telnet,telnetd(默认也是支持的) 然后make;make install2、制作根文件系统下面标红的就是需要自己添加进去的(etc/init.d/rcS) 还有需要注意,pts/0表示可以同时开一个telnet端口登录,如果需要多个人同时登录,则需要多添加原创 2015-04-16 10:43:25 · 2882 阅读 · 0 评论 -
一步一步学习 Linux 驱动之字符设备 LED
http://download.csdn.net/detail/xy010902100449/8594831 所有的驱动程序都应该对应一个具体的设备,这个LED驱动当然设备应该是LED。但是linux将它分成了一类叫做混杂设备。这类设备共享一个主设备号,但次设备号不同所有混杂设备形成一个链表,要访问一个设备时根据次设备号来查找相应的miscdevice。linux中用struct miscdevice来描述一个混杂设备。程序必须根据自己根文件系统内核位置来写MakeFile,否则编译很容易通过不了。原创 2015-04-14 16:17:07 · 1739 阅读 · 0 评论