首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux内核驱动编写

大家好,又见面了,我是你们朋友全栈君。 # 前言 开发过单片机小伙伴可以看一下我之前一篇文章从单片机开发到linux内核驱动,以浅显易懂方式带你敲开Linux驱动开发大门。...# 正文 用户空间每个函数(用于使用设备或者文件),在内核空间中都有一个对应功能相似并且可将内核信息向用户空间传递函数。 下表为几种设备驱动事件和它们在内核和用户空间对应接口函数。...但是模块加载到内核,还是不能用,得有具体设备才能用。 如果驱动模块中有实现自动生成当前设备文件节点代码,那么会使用和热拔插相关代码脚本,自动在/dev下面生成对应设备文件。...如果没有,只能自己手动来生成这个设备文件。当然最终都要运行mknod命令,它会根据你传进去主次设备号和类型。在内核维护设备和驱动列表寻找你在驱动模块中注册设备和驱动。...如果找到了,会生成相关文件节点,并在节点内部存下相关驱动信息,当你打开或者读写文件节点时候,最终会调用到你注册驱动相关驱动函数。

7.1K20

Linux内核设备驱动Linux内核基础笔记整理

Linux内核驱动模块机制 静态加载, 把驱动模块编进内核, 在内核启动时加载 动态加载, 把驱动模块编为ko, 在内核启动后,需要用时加载 2....编写内核驱动 #include #include static int __init test_init(void) { return...0; //返回0表示成功, 返加负数退出加载模块 } //__init 当内核驱动初始化完后, 释放此函数代码指令空间 static void __exit test_exit(void) { ....驱动模块Makefile obj-m += test.o //源码文件为test.c modules:make -C 内核源码目录 M=驱动代码所在目录 modules modules install...:make -C 内核源码目录 M=驱动代码所在目录 modules_install INSTALL_MOD_PATH=/文件系统路径 clean:make -C 内核源码目录 M=驱动代码所在目录

1.8K51
您找到你想要的搜索结果了吗?
是的
没有找到

谈谈Linux内核驱动coding style

最近在向Linux内核提交一些驱动程序,在提交过程,发现自己代码离Linux内核coding style要求还是差很多。...如果去看drivers/staging下代码,就会发现很多驱动程序都没有严格遵守内核coding style,而且在很多驱动程序TODO文件里,都会把"checkpatch.pl fixes"作为自己目标之一...如果用来检查原文件,需要加上“-f”选项。...在Linux内核coding style里,switch和case要求有相同缩进。本例代码很少,错误也只有这一个,手动修改很方便。如果类似的缩紧错误很多怎么办?...比如,Linux内核coding style要求,行尾不能有空格(包括Tab),去除这些空格就可以借助sed。 我自己习惯很差,经常在代码行尾留下一些空格。

1.7K10

linux内核驱动模型详解_arduino驱动安装

转载请标明出处floatercsdn blog,http://blog.csdn.net/flaoter Linux SPI驱动分为核心层,控制器驱动层和设备驱动层。...核心层是LinuxSPI核心部分,提供了核心数据结构定义,总线、设备和驱动注册、注销管理等,提供与上层统一接口。...linux将I2C、SPI、USB等总线驱动隔离成控制器驱动和设备驱动,使两者相对独立。 本文以qcomspi控制器为例,对spi控制器驱动进行解析。kernel代码版本是3.18。...linux驱动与设备是一对多关系,在spi_master设备注册时,控制器结构体信息会提供给spi_master作为私有数据。...它probe依赖于dts设备compatible属性与驱动of_device_id比对结果,一致情况下,probe会被加载执行。

11.1K40

Linux内核设备驱动之proc文件系统笔记整理

/proc下面的每个文件都绑定于一个内核函数,用户读取文件时,该函数动态地生成文件内容。...也可以通过写/proc文件修改内核参数 /proc目录下文件分析 /proc/$pid关于进程$pid信息目录。每个进程在/proc 下有一个名为其进程号目录。...与物理内存大小完全一样,但不实际占用这么多内存;(记住:除非拷贝到文件,/proc下没有任何东西占用任何磁盘空间) /proc/kmsg 内核输出消息。也被送到syslog。...供uptime使用 /proc/version 内核版本 (2)自行实现一个/proc文件 需包含头文件,函数定义在/fs/proc/generic.c a.在/proc...*parent); c.定义返回数据函数 在进程读取/proc文件时,内核会分配一个内存页(即PAGE_SIZE个字节内存块),驱动将要写数据通过这个内存页返回到用户空间。

3.5K21

Linux 内核之字符设备驱动

支持阻塞IO驱动demo Linux设备类型可以大概分为以下几种: 字符设备:以字节为单位传输,传输率低,不支持随机访问,常见设备有鼠标,键盘,触摸屏等 块设备: 以块位单位传输,常见就是磁盘...先看下字符设备结构 struct cdev { struct kobject kobj; // 用于linux设备驱动模型 struct module *owner; // 字符设备驱动所在内核模块对象指针...const struct file_operations *ops; // 字符设备驱动中最关键一个操作函数,在和应用程序交互过程起枢纽作用 struct list_head list...提到多路复用,就是linux著名poll,epoll,select机制,在内核对应文件方法就是: __poll_t (*poll) (struct file *, struct poll_table_struct...*); 用户态对设备执行poll或select,设备驱动poll方法就会被调用,poll会执行以下步骤: 在一个或多个等待队列调用poll_wait, 该函数会把当前进程加到执行等待列表(poll_table

4.8K40

Linux内核设备驱动内核调试技术笔记整理

/****************** * 内核调试技术 ******************/ (1)内核源代码一些与调试相关配置选项 内核配置选项包含了一些与内核调试相关选项,都集中在...包括: CONFIG_DEBUG_KERNEL 使其他调试选项可用,应该选中,其本身不会打开所有的调试功能。 具体调试选项说明可参见驱动一书,或通过menuconfighelp说明查看。...(2)如何通过宏对printk调试语句进行全局控制 通过和Makefile配合,可以在c文件定义属于我们自己调试语句。...有用参数有: -t 显示调用发生时间 -T 显式调用所花费时间 -f 跟踪所有子进程 -p 跟踪特定进程 -o 将输出信息导入特定文件 (5)查看oops消息 oops是内核告知用户有不幸发生最常用方式...在某些情况下,oops会导致内核混乱,而混乱结果就是死机,这些情况可能包括: *oops发生在持有锁代码 *oops发生在和硬件设备通讯过程 *oops在中断上下文中发生 *oops发生在idle

2.1K41

如何调整Linux内核启动驱动初始化顺序?

如何调整Linux内核启动驱动初始化顺序? 【问题】 此处我要实现是将芯片ID用于网卡MAC地址,网卡驱动是enc28j60_init。...【解决过程】 【1】 最简单想到,是内核里面的 arch\arm\mach-as352x\core.c ,去改devices设备列表顺序。...【2】 在网上看到很多帖子,其说明也很清楚了,就是: Linux内核为不同驱动加载顺序对应不同优先级,定义了一些宏: include\linux\init.h #define pure_initcall...当然,对应编译生成system.map文件,对应通过module_init定义驱动,优先级也都变成7了。而late_initcall对应优先级8了。...注:当前开发板arm板子,所以,对应load 脚本在: linux-2.6.28.4\arch\arm\kernel\vmlinux.lds 看起来,应该是这个文件linux-2.6.28.4\

3.9K31

Linux内核LED设备驱动框架【转】

驱动框架概念 内核驱动部分维护者针对每个种类驱动设计一套成熟、标准、典型驱动实现,并把不同厂家同类硬件驱动相同部分抽出来自己实现好,再把不同部分留出接口给具体驱动开发工程师来实现,这就叫驱动框架...因此,LinuxLED驱动框架把所有LED设备共性给实现了,把不同地方留给驱动工程师去做。...内核在启动过程内核需要按照先后顺序去进行初始化操作。因此,内核给是给启动时要调用所有初始化函数归类,然后每个类按照一定次序去调用执行。...详见Linux设备管理:sysfs文件系统功能及其应用。 led_class_attrs结构体数组设置了leds设备类属性,即led硬件操作对象和方法。.../kernel/include/linux/sysfs.h *_name表示属性名字,即在sys呈现文件

2.5K10

Linux内核驱动开发EXPORT_SYMBOL

简介 本文主要来讲讲Linux内核驱动,EXPORT_SYMBOL()宏定义用法。 在阅读Linux内核驱动源码时候,我们会发现很多函数带有EXPORT_SYMBOL()宏定义。...从这个宏定义理解为输出符号。那么他究竟有什么作用。...EXPORT_SYMBOL()宏定义作用 EXPORT_SYMBOL宏定义定义函数或者符号将对内核代码公开,不用修改内核代码就在其他内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号方式导出给其他模块使用...extern int rice_func(void); 先加载定义该函数模块,然后再加载调用该函数模块,先后顺序必须注意。...实验 编写代码 编写两个模块:rice_export.ko 和 rice_import.ko,其中: rice_export.ko:导出定义函数 rice_import.ko:调用导出函数 导出函数模块代码

2.4K20

Linux内核设备驱动之虚拟文件系统笔记整理

对于不基于磁盘文件系统,比如基于内存文件系统sysfs,linux会在使用现场创建超级块并将其保存到内存。 超级块结构体为super_block,定义在。...在文件系统安装时,内核会调用alloc_super()函数从磁盘读取文件系统超级块,并将其信息填充到内存超级块对象。...b.索引节点对象inode 索引节点对象包含了内核在操作文件或目录是需要全部信息,如文件访问控制权限,大小,拥有者,创建时间等。 系统把这些信息存储在一个单独数据结构,称为索引节点。...dentry结构体定义在,对应目录项操作函数结构体dentry_operations也定义在。...文件对象由file结构体表示,定义在。file对象操作函数结构体为file_operations,定义在

2.1K20

驱动开发:内核遍历文件或目录

在笔者前一篇文章《驱动开发:内核文件读写系列函数》简单介绍了内核如何对文件进行基本读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能实现需要依赖于ZwQueryDirectoryFile...这个内核API函数来实现,该函数可返回给定文件句柄指定目录中文件各种信息,此类信息会保存在PFILE_BOTH_DIR_INFORMATION结构下,通过遍历该目录即可获取到文件详细参数,如下将具体分析并实现遍历目录功能...); 该函数我们需要注意FileInformation参数,在本例它被设定为了PFILE_BOTH_DIR_INFORMATION用于存储当前节点下文件或目录一些属性,如文件名,文件时间,文件状态等...,其次FileInformationClass参数也是有多种选择,本例我们需要遍历文件或目录则设置成FileBothDirectoryInformation就可以,在循环遍历文件时需要将当前目录.以及上一级目录...你是否会觉得很失望,为什么不是递归枚举,这里为大家解释一下,通常情况下ARK工具并不会在内核层实现目录与文件递归操作,而是将递归过程搬到了应用层,当用户点击一个新目录时,在应用层只需要拼接新路径再次发送给驱动程序让其重新遍历一份即可

18440

Linux内核设备驱动内核时间管理笔记整理

/****************** * linux内核时间管理 ******************/ (1)内核时间概念 时间管理在linux内核占有非常重要作用。...相对于事件驱动而言,内核中有大量函数是基于时间驱动。 有些函数是周期执行,比如每10毫秒刷新一次屏幕; 有些函数是推后一定时间执行,比如内核在500毫秒后执行某项任务。...要区分: *绝对时间和相对时间 *周期性产生事件和推迟执行事件 周期性事件是由系统系统定时器驱动 (2)HZ值 内核必须在硬件定时器帮助下才能计算和管理时间。...如果在驱动要使用系统中断频率,直接使用HZ,而不要用100或1000 a.理想HZ值 i386HZ值一直采用100,直到2.5版后才改为1000。...休眠函数文件是,具体实现函数在kernel/wait.c

2.5K31

驱动开发:内核遍历文件或目录

在笔者前一篇文章《驱动开发:内核文件读写系列函数》简单介绍了内核如何对文件进行基本读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能实现需要依赖于ZwQueryDirectoryFile...这个内核API函数来实现,该函数可返回给定文件句柄指定目录中文件各种信息,此类信息会保存在PFILE_BOTH_DIR_INFORMATION结构下,通过遍历该目录即可获取到文件详细参数,如下将具体分析并实现遍历目录功能...;该函数我们需要注意FileInformation参数,在本例它被设定为了PFILE_BOTH_DIR_INFORMATION用于存储当前节点下文件或目录一些属性,如文件名,文件时间,文件状态等,其次...FileInformationClass参数也是有多种选择,本例我们需要遍历文件或目录则设置成FileBothDirectoryInformation就可以,在循环遍历文件时需要将当前目录.以及上一级目录...,为什么不是递归枚举,这里为大家解释一下,通常情况下ARK工具并不会在内核层实现目录与文件递归操作,而是将递归过程搬到了应用层,当用户点击一个新目录时,在应用层只需要拼接新路径再次发送给驱动程序让其重新遍历一份即可

47660

驱动开发:内核文件读写系列函数

在应用层下文件操作只需要调用微软应用层下API函数及C库标准函数即可,而如果在内核读写文件则应用层API显然是无法被使用内核层需要使用内核专有API,某些应用层下API只需要增加Zw开头即可在内核中使用...首先无论在内核态还是在用户态,我们调用文件操作函数其最终都会转换为一个IRP请求,并发送到文件系统驱动IRP_MJ_READ派遣函数里面,这个读写流程大体上可分为如下四步; 对于FAT32分区会默认分发到...创建文件或目录: 实现创建文件或目录,创建文件或目录都可调用ZwCreateFile()这个内核函数来实现,唯一不同区别在于当用户传入参数包含有FILE_SYNCHRONOUS_IO_NONALERT...: 在内核重命名文件或目录核心功能实现依赖于ZwSetInformationFile()这个内核函数,该函数可用于更改有关文件对象各种信息,其微软官方定义如下; NTSYSAPI NTSTATUS...程序大小字节数,如下图所示; 内核文件读写: 内核读取文件可以使用ZwReadFile(),内核写入文件则可使用ZwWriteFile(),这两个函数参数传递基本上一致,如下是读写两个函数对比参数

30020

驱动开发:内核文件读写系列函数

在应用层下文件操作只需要调用微软应用层下API函数及C库标准函数即可,而如果在内核读写文件则应用层API显然是无法被使用内核层需要使用内核专有API,某些应用层下API只需要增加Zw开头即可在内核中使用...首先无论在内核态还是在用户态,我们调用文件操作函数其最终都会转换为一个IRP请求,并发送到文件系统驱动IRP_MJ_READ派遣函数里面,这个读写流程大体上可分为如下四步;对于FAT32分区会默认分发到...创建文件或目录: 实现创建文件或目录,创建文件或目录都可调用ZwCreateFile()这个内核函数来实现,唯一不同区别在于当用户传入参数包含有FILE_SYNCHRONOUS_IO_NONALERT...: 在内核重命名文件或目录核心功能实现依赖于ZwSetInformationFile()这个内核函数,该函数可用于更改有关文件对象各种信息,其微软官方定义如下;NTSYSAPI NTSTATUS...程序大小字节数,如下图所示;图片内核文件读写: 内核读取文件可以使用ZwReadFile(),内核写入文件则可使用ZwWriteFile(),这两个函数参数传递基本上一致,如下是读写两个函数对比参数

65380

驱动开发:内核自旋锁结构

提到自旋锁那就必须要说链表,在上一篇《驱动开发:内核链表与结构体》文章简单实用链表结构来存储进程信息列表,相信读者应该已经理解了内核链表基本使用,本篇文章将讲解自旋锁简单应用,自旋锁是为了解决内核链表读写时存在线程同步问题...,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供一种高IRQL锁,用同步以及独占方式访问某个资源。...ULONG y; LIST_ENTRY lpListEntry;}MyStruct,*pMyStruct;VOID UnDriver(PDRIVER_OBJECT driver){ DbgPrint("驱动卸载成功...,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供一种高IRQL锁,用同步以及独占方式访问某个资源。...锁内部执行 \n");// 释放锁KeReleaseSpinLock(&my_list_lock, Irql);}VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("驱动卸载成功

27220

驱动开发:内核自旋锁结构

提到自旋锁那就必须要说链表,在上一篇《驱动开发:内核链表与结构体》文章简单实用链表结构来存储进程信息列表,相信读者应该已经理解了内核链表基本使用,本篇文章将讲解自旋锁简单应用,自旋锁是为了解决内核链表读写时存在线程同步问题...,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供一种高IRQL锁,用同步以及独占方式访问某个资源。...LIST_ENTRY lpListEntry; }MyStruct,*pMyStruct; VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驱动卸载成功...,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供一种高IRQL锁,用同步以及独占方式访问某个资源。.../ 释放锁 KeReleaseSpinLock(&my_list_lock, Irql); } VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驱动卸载成功

31410
领券