【Linux】驱动的基本架构和编译

devtools/2024/10/18 8:28:16/

驱动源码

/**  Silicon Integrated Co., Ltd haptic sih688x haptic driver file**  Copyright (c) 2021 kugua <daokuan.zhu@si-in.com>** This program is free software; you can redistribute it and/or modify it* under the terms of the GNU General Public License version 2 as published by* the Free Software Foundation*/#include <linux/init.h>  //包含宏定义的头文件
#include <linux/module.h>   //包含初始化加载模块的头文件static int __init haptics_init(void)
{//内核层只能使用printk,不能使用printfprintk(KERN_EMERG "[ KERN_EMERG ]  Haptics Init\n"); //输出等级为0printk("[ default ]  Haptics Init\n");return 0;
}static void __exit haptics_exit(void)
{printk(KERN_EMERG "[ KERN_EMERG ]  Haptics Exit\n"); //输出等级为0printk("[ default ]   Haptics Exit\n");
}module_init(haptics_init);//驱动入口
module_exit(haptics_exit);//驱动出口MODULE_AUTHOR("<daokuan.zhug@si-in.com>");//声明作者信息
MODULE_DESCRIPTION("Haptic Driver V1.0.0"); //对这个模块作一个简单的描述
MODULE_LICENSE("GPL v2");//声明开源许可证// "GPL" 是指明 这是GNU General Public License的任意版本// “GPL v2” 是指明 这仅声明为GPL的第二版本
  • linux驱动基本框架就是包含入口函数和出口函数,加载驱动时会运行入口函数,卸载驱动时会运行出口函数。
  • 入口函数的作用是加载驱动时做一些初始化工作,比如注册设备、申请设备号、生成设备节点等,上文代码中这些都还没有实现。
  • 出口函数的作用是卸载驱动时做一些善后操作,比如注销设备、注销设备号、注销类等。
  • 在内核态下的打印函数是“printk”函数。KERN_EMERG是打印优先级,这里采用了最高优先级。

一般情况下,驱动源码会放在kernel/drivers,里面会有很多文件夹存放不同的驱动代码,我们自己的驱动需要新建一个目录。

在这里插入图片描述

Kconfig文件

这个文件时用来对内核进行配置的,当执行make arch=ARM64 menuconfig指令的时候,这个文件就被解析。该文件和源码文件在同一目录下,文件内容可如下:

menu "haptics driver"config HAPTICS
tristate "haptics driver"
helpjust a simplest driver.
default yendmenu
#endmenu后一定要加空行
  • 第一行内容表示菜单名
  • 第二行内容config HAPTICS,在执行配置的时候,将会生成一个变量 CONFIG_HAPTICS,而这个变量,将会在编译的时候,被 Makefile 引用。
  • 第三行内容tristate声明选项的类型,"haptics driver"声明选项的名称
  • 第四行内容表示帮助信息
  • 第五行的 default y ,就表示把 CONFIG_HAPTICS 的值设置成 y,从而让这个驱动被编译到内核中。
  • 第六行是结束菜单
  • 第七行是需要加的空行

其中第三行内容的选项支持tristatebool

tristate支持三个选项:

  • < >不编译
  • <*>编译到内核
  • 编译成模块

bool支持两个选项:

  • < >不编译
  • <*>编译到内核

这个在菜单配置时我们会碰到。

现在,haptics驱动中的KConfig配置文件已经准备好了,但是还需要这个配置文件登记到 Linux内核的整体配置文件中。也就是把它登记到kernel/drivers/Kconfig 文件的末尾:

source "drivers/haptics/Kconfig"endmenu // 加在这一句的上面

然后在kernel目录下执行make ARCH=arm64 menuconfig命令,

在这里插入图片描述

在这里插入图片描述

我们可以看到haptics driver前面显示的是星号*,这表示:该驱动将会编译进内核。我们可以按下空格键切换标记。M标记意思是编译成驱动模块。

我们暂时先选择星号编译进内核,其他的选项后续再介绍。最后选择save即可。

有一点需要注意的,如果Kconfig是在Windows系统上编辑的然后放在开发服务器中,我们会发现报警了

zhudk@vm1:/expand/zhudk/rk3588_9tripod/x3588_linux_20220620/kernel$ make ARCH=arm64 menuconfig
'rivers/haptics/Kconfig:1:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:2:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:3:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:5:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:6:warning: ignoring unsupported character '

这是因为在Windows和Linux系统中,存在换行符的差异。这个小问题可以自行解决。

Makefile文件

Makefile文件是make工具的脚本,也是和源码放在同一目录下,其内容只有一行。

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

现在,haptics驱动程序的Makefile已经创建好了,我们还要让linux内核的编译框架知道这个文件才行。在文件kernel/drivers/Makefile 中的末尾,添加如下内容:

obj-$(CONFIG_HAPTICS)           += haptics/

编译进内核

在这里插入图片描述

现在,整个准备工作已经做好了,只需编译即可。因为本篇教程是基于ARM开发板的,所以使用开发板中SDK的编译脚本进行内核编译。

./build.sh kernel

然后将编译的镜像文件烧录至开发板中,关于编译烧录等可参考【rk3588】环境搭建及系统编译_rk3588 arm64-CSDN博客。在启动日志中,我们可以看到如下信息:

在这里插入图片描述

这个正好是我们在驱动入口函数中的打印信息,所以也证明了我们的驱动程序编译进内核并且正常运行了。

编译为驱动模块

上文我们介绍的是将驱动编译进内核,如果需要编译为驱动模块,直接在Kconfig文件中将default y修改为default m。然后执行

./build.sh modules

表示编译内核模块,也仅仅编译设置为模块的驱动,然后会在驱动目录下生成haptics.ko文件。这个文件需要我们手动安装卸载,但首先得发送到开发板上。

在这里插入图片描述

总结

驱动的编译分为两种方式:

编译进内核:

  • Kconfig文件中配置为default y
  • 执行./build.sh kernel指令进行编译
  • 上述指令是编译整个内核,编译后将镜像文件烧录至开发板,驱动会自动加载

编译为模块:

  • Kconfig文件中配置为default m
  • 执行./build.sh modules指令进行编译
  • 上述指令是编译驱动模块,编译结果只有.ko文件,需要上传至开发板手动加载(开发板提前烧录好不含驱动的镜像)

这两种方式具体使用哪一个呢,需要视具体情况。但是好像可以不需要使用界面配置,还是直接修改配置文件比较方便。


http://www.ppmy.cn/devtools/118394.html

相关文章

血缘解析<三>:如何解析DML语句?

blood 一、insert...select...on duplicate update...二、update...join...on...set... 本文案例只针对Mysql中的语句,其它数据库的DML语句可自行扩展 一、insert…select…on duplicate update… eg: insert into test (id,name,age) select id,name,age from test1 ton du…

SQL 简介

SQL 简介 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种广泛使用的数据库语言&#xff0c;用于管理关系数据库系统、处理数据以及执行各种数据操作任务。它是由IBM开发的&#xff0c;并在1986年成为美国国家标准协会&#xff08;ANS…

算法分类自动驾驶主要算法介绍

算法的基本分布结构 自动驾驶主要算法介绍 算法的基本分布结构 行业算法&#xff1a; 行业算法是根据特定行业和专业领域的特定问题&#xff0c;将计算逻辑模块调取组合&#xff0c;并应用此行业数据训练形成的计算模式。常见的行业算法如无人驾驶&#xff0c;AI医疗诊断&am…

读书笔记--结合自身经历和乡土中国的阅读总结思考

经过前两篇的阅读感悟&#xff0c;最近受爱人和大家的启发&#xff0c;建议我结合自身的人生经历和《乡土中国》写一篇总结感悟&#xff0c;因此本篇将结合自身经历进行总结思考。我自己其实和董宇辉非常类似&#xff08;当然和他比差远了&#xff0c;我的知识储备、思考感悟、…

css实现自定义静态进度条-vue2

实现如图所示 html&#xff1a; <div class"progress-container"><div class"progress-box left" :style"leftStyle"><div class"progress-value-top left">总中标电量</div><div class"progress-val…

828华为云征文|使用Flexus X实例创建FDS+Nginx服务实现图片上传功能

一、Flexus X实例 什么是Flexus X实例呢&#xff0c;这是华为云最新推出的云服务器产品&#xff0c;如下图&#xff1a; 华为云推出的Flexus云服务器X系列&#xff0c;是在华为顶尖技术团队&#xff0c;特别是荣获国家科技进步奖的领军人物顾炯炯博士及其团队的主导下精心研发…

第三十二章 使用派生密钥令牌进行加密和签名 - 使用 DerivedKeyToken 进行加密

文章目录 第三十二章 使用派生密钥令牌进行加密和签名 - 使用 <DerivedKeyToken> 第三十二章 使用派生密钥令牌进行加密和签名 - 使用 进行加密 要使用 <DerivedKeyToken> 进行加密&#xff0c;请使用以下步骤&#xff1a; 如果要加密一个或多个安全标头元素&a…

这才是CSDN最系统的网络安全学习路线(建议收藏)

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…