当前位置:网站首页 > Go语言开发 > 正文

linux内核驱动开发教程(linux内核驱动程序)



别人的经验,我们的阶梯!

大家好,我是道哥。今天给大家分享一些笔记本里的一些存货: Linux 系统中的驱动和中断相关。

大概会用 6~7 篇的文章,由浅入深的为大家介绍 中驱动程序的编写方法。

文章的顺序,也是我之前自己学习时的顺序。

以前的学习记录比较零散,现在只是把它们按照一定的顺序重新梳理一下。

这几篇文章,理论知识会少一些,更注重实际的操作。

我会把操作用引导的代码,全部上传到网盘上,在文末有下载说明。

只要根据文中介绍的步骤进行操作,就一定可以操作成功。

记得以前我在开始学习驱动开发的时候,找来很多文章、资料来学习,但是总是觉得缺少了点全局视角。

就好像:我想看清一座山的全貌,但总是被困在一个、又一个山谷中一样。

主要的困惑有 3 点:

  1. 每一篇文章的介绍都是正确的,但是如果把很多文章放在一起看,就会发现怎么说的都不一样啊?
  2. 有些文章注重函数的介绍,但是缺乏一个全局的视角,从整体上来观察驱动程序的结构;
  3. 对于一个新手来说,能够边学习、边实践,这是最好的学习方式,但是很多文章不会注意这方面。虽然文章内容很漂亮,但是不知道怎么去实践、验证。

因此,这几篇文章我们就从最简单的驱动模块编译开始,然后介绍字符设备驱动程序。

在这部分,会以 GPIO 为例子,重点描述其中的关键节点。

最后再介绍在中断处理程序中,如何利用信号量、小任务、工作队列,把内核事件传递到应用层来处理。

作为第一个开篇文章,从最简单的内核编译开始。

实际操作一下:如何把一个最简单的驱动程序(),按照 2 种方式进行编译:

  1. 编译进内核;
  2. 编译为一个独立的驱动模块;

为了便于测试,以下操作都是在 Ubuntu16.04 操作系统里完成的。

编译驱动程序,肯定需要内核源码,这里选择的是 linux-4.15 版本,可以在官网下载。

文末有下载方式。

下载之后,把解压到中任意目录即可,例如:解压到目录下:

 
创建驱动程序目录

中的驱动,一般都放在 linux-4.15/drivers/ 目录下,因此在这个目录中创建一个文件夹。

 

对于一个驱动来说,最重要的就是个文件:

  1. 源代码
  2. Kconfig
  3. Makefile

只要按照固定的格式来编写这个文件,内核的编译脚本就可以确保把我们的驱动程序编译进去。

创建源文件

首先是源码,在文件夹中创建源文件:

 

源文件的内容是:

 

有两个小地方注意一下:

  1. 在内核中,打印函数是 printk,而不是 printf;
  2. 打印信息的级别有好几个,从 DEBUG 到 EMERG,这里使用的是 KERN_ALERT,方便查看打印信息。
创建 Kconfig 文件

这个文件是用来对内核进行配置的,当执行 make menuconfig 指令的时候,这个文件就被解析。

先创建文件:

 

添加如下内容:

 

第一行内容 config HELLO ,在执行配置的时候,将会生成一个变量 CONFIG_HELLO ,而这个变量,将会在编译的时候,被 Makefile 引用。

最后一行的 default y ,就表示把 CONFIG_HELLO 的值设置成 y,从而让这个驱动被编译到内核中。

现在,驱动中的配置文件已经准备好了,但是还需要这个配置文件登记到 内核的整体配置文件中。

也就是把它登记在 linux-4.15/drivers/Kconfig 文件的末尾:

 

现在,可以来执行下面指令,看一下具体的配置界面:

 

第条指令,是用来把默认的配置保存到当前目录下的 .config 配置文件,也就是把一个默认的配置文件复制过来,作为我们自己的配置文件。

以后再修改配置参数时,修改的内容就会存储在 .config 文件中,

第条指令,是用来配置内核的,可以进入  菜单,然后在最底层看到我们的  被标记成星号,
这表示被编译进内核。

按向下方向键,把高亮定位到 Device Drivers ---> ,然后敲回车键,进入到 Device Drivers 的配置界面。

按向下方向键,一直到最后一个条目,就可以看到我们的 hello 驱动了,如下:

可以看到 hello driver 前面显示的是型号 *,这表示:该驱动将会编译进内核。

我们可以按下空格键试一下,会在三种标记中切换:型号,M,空值。M 标记意思是编译成驱动模块。

我们这里选择星号(编译进内核),然后按下右方向键,最下方的几个按键的焦点移动到 按钮上:

按下回车键,就会弹出保存对话框,选择默认保存文件 .config 即可,然后在 按钮高亮的时候,按下回车键即可保存。

此时,在弹出的确认窗口中,选择,按下回车键即可:

此时,返回到 Device Drivers 的配置界面,在最下面的按钮中,选择让高亮,然后一路退出即可。

创建 Makefile 文件

文件是工具的脚本,首先创建它:

 

其中的内容只有一行:

 
  1. CONFIG_HELLO 可以看做一个变量,在编译的时候,这个变量的值可能是:y, n 或者 m。
  2. 在刚才的 Kconfig 参数配置中,CONFIG_HELLO 被设置为 y,于是这句话就被翻译成: obj-y += hello,表示把 hello 驱动编译进内核。

现在,驱动程序的已经创建好了,我们还要让内核的编译框架知道这个文件才行。

在文件 linux-4.15/drivers/Makefile 中的末尾,添加如下内容:

 
编译

万事俱备,只欠编译!依次执行如下指令:

 

指令执行结束之后,编译得到的内核中()就包含了我们的驱动。

编译为驱动模块,也有两种 操作方式:

编译所有的驱动模块
  1. 在执行 make ARCH=x86_64 menuconfig 指令的时候,把 hello 配置成 M;
  2. 然后在 linux-4.15 中执行编译模块指令:make -j4 modules。

编译成功之后,就可以得到文件: linux-4.15/drivers/hello/hello.ko。

这样的编译指令,是把所有的模块都编译了一次(在输出信息中,可以看到编译了很多模块)。

只编译 hello 这一个驱动模块

另外一种编译驱动模块的方式是:进入目录,只编译这一个驱动模块。

这种编译方法,就需要修改目录下的文件了,内容如下:

可以把 hello 目录下的所有文件删除,只保留源文件 hello.c,然后新建 Makefile 文件。

 

然后,在文件夹中执行指令,即可得到驱动模块 hello.ko 。

验证一下

加载驱动:

 

此时终端窗口是没有任何输出的,需要输入指令 dmesg | tail ,可以看到 hello_init 函数的输出内容:

卸载驱动:

 

再次输入 dmesg | tail ,可以看到 hello_exit 函数的输出内容:

在公众号【IOT物联网小镇】的后台回复关键字:1112,获取下列文件的网盘地址:

linux-4.15.tar.gz

hello文件夹压缩包

------ End ------

推荐阅读
 

【1】《Linux 从头学》系列文章

【2】C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻

【3】原来gdb的底层调试原理这么简单

【4】内联汇编很可怕吗?看完这篇文章,终结它!

到此这篇linux内核驱动开发教程(linux内核驱动程序)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 预训练语言模型(预训练语言模型可以解决什么问题)2025-03-25 18:00:04
  • bsp开发和驱动开发的区别(bsp工程师和驱动工程师的区别)2025-03-25 18:00:04
  • 开发者账号注册(开发者账号注册流程中需要注意什么)2025-03-25 18:00:04
  • linux驱动开发(linux驱动开发工资)2025-03-25 18:00:04
  • bsp驱动开发(bsp驱动开发怎么学)2025-03-25 18:00:04
  • linux内核驱动开发 vscode(linux内核驱动开发前景)2025-03-25 18:00:04
  • linux内核驱动开发常用知识(linux内核驱动开发圣经pdf)2025-03-25 18:00:04
  • 数的合并c语言(合并整数c语言)2025-03-25 18:00:04
  • ifstream good函数(ifstream open函数)2025-03-25 18:00:04
  • 预训练语言模型(预训练语言模型pdf下载百度网盘)2025-03-25 18:00:04
  • 全屏图片