当前位置: 首页 > news >正文

基于linux内核的驱动开发学习


1 驱动
    定义:驱使硬件动起来的程序
    种类:裸机驱动:需求分析--》查原理图--》查芯片手册--》code
            系统驱动:需求分析--》查原理图--》查芯片手册--》设备树--》code
                        --》安装到内核中
     裸机开发&系统开发的优缺点?
    裸机开发:成本低  运行效率高 安全性低 单任务
    系统开发:成本高  运行效率低 安全性低 多任务
             应用程序和驱动程序的区别?
                        应用程序                驱动程序  
    1 加载方式    主动加载                被动加载  
    2 运行空间    用户空间                 kernel空间
    3 执行权限    低                           高
    4 影响力        局部                       全局
    5 函数来源     自定义/库/系统调用    内核函数/自定义

2 模块--》驱动模块
        模块:能够单独命名并且独立完成一定功能的程序语句的集合(程序代码和数据结构)
        驱动模块:能够单独命名并且独立完成特定外设功能驱动的程序语句的集合
         注:一个驱动模块就是一个完整的外设驱动程序,驱动程序被安装到操作系统内核中,
            当该驱动程序对应的外设要工作时,该驱动模块被调用。
    2.1如何写一个驱动模块?
        1 模块初始化函数   int 函数名1(void)
        2 模块清除函数     void 函数名2(void)
        3 模块加载函数     module_init(函数名1)--》sudo insmod hello.ko
        4 模块卸载函数     module_exit(函数名2)--》sudo rmmod hello.ko
        5 声明该驱动遵守GPL--》MOUDULE_LICENSE("GPL”)

    《include/linux/init.h》
    #define module_init(initfn)                    \
    static inline initcall_t __inittest(void)        \
    { return initfn; }    

    #define module_exit(exitfn)                    \
    static inline exitcall_t __exittest(void)        \
    { return exitfn; }
    2.2如何编译驱动模块
        hello.c-->hello.ko
        test.c-->a.out
        需要实现一个Makefile:
        Makefile:
        ifeq ($(KERNELRELEASE),)
            KERNELDIR ?= /lib/modules/$(shell uname -r)/build   
            PWD := $(shell pwd)
        modules:
            $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
            //进入/lib/modules/3.5.0-23-generic/build下执行Makefile,        
            将PWD路径下的代码编译成一个hello.o
        else
                obj-m := hello.o  //将hello.o链接成hello.ko
        endif
        
        clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions 
        Module* modules*
    3.3 将驱动模块安装到Linux内核中
         sudo insmod hello.ko-->将驱动模块hello.ko安装到linux内核中
         lsmod-->查看当前系统中所有已加载的驱动模块
         dmesg |tail-->查看内核缓存区后10行打印信息
         dmesg |tail  -20-->查看内核缓存区后20行打印信息
         modinfo hello.ko-->查看模块信息描述
         sudo rmmod hello.ko-->将hello.ko从内核中移除
     3.4将驱动代码分成两个文件
        hello.c-->hello_init.c&hello_exit.c-->hello_init.o&hello_exit.o-->hello.ko
        需要实现一个Makefile:
        Makefile:
        ifeq ($(KERNELRELEASE),)
            KERNELDIR ?= /lib/modules/$(shell uname -r)/build   
            PWD := $(shell pwd)
        modules:
            $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
            //进入/lib/modules/3.5.0-23-generic/build下执行Makefile,        
            将PWD路径下的代码编译成一个hello.o
        else
                obj-m := hello.o  //将hello.o链接成hello.ko
            hello-objs=hello_init.o hello_exit.o//将两个.o文件连接成一个hello.o文件
        endif
        
        clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions 
        Module* modules*
         
    3 模块传参
        应用程序:
            传参:./a.out  1.txt 2.txt
            接收传参:int main(int argc,char *argv[])
        驱动程序:
            传参:安装驱动模块时传  sudo insmod hello.ko gtest=100
            接收传参:1 用全局变量  int gtest;
                          2 声明该全局变量接收传参

            如何声明一个全局变量可以接收shell终端的参数传递?用内核函数声明
            module_param(name, type, perm)
            name:参数名,既是内部参数名,又是外部参数名
            type:参数的数据类型
            perm:访问权限,0644。0表示该参数在文件系统中不可见

            module_param_string(name, string, len, perm)
            name:外部参数名
            string:内部参数
            len:数组的大小
            perm:访问权限,0644。0表示该参数在文件系统中不可见

            module_param_array(name, type, nump, perm)
            name:数组参数名,既是内部参数名,又是外部参数名
            type:参数的数据类型(数组成员的数据类型)
            nump:用来存放终端传给数组的实际元素个数
            perm:访问权限,0644。0表示该参数在文件系统中不可见

            测试步骤:
                1 sudo insmod hello.ko gtest=100
                2 dmesg |tail-->查看gtest的值是否是100?
                3 cd /sys/module/hello/paramters
                        ls -l--->gtest  
                        cat gtest-->100?
                        sudo chmod 777 gtest
                        echo 200 > gtest
                        cat gtest-->200?
                4 sudo rmmod hello.ko
                5 dmesg |tail-->gtest=200?
    4 符号导出
        1 什么是符号?在内核和驱动中主要是指全局变量和函数
        2 为什么要导出符号?
            linux内核是以模块化形式管理内核代码的。内核中的每个模块之间是相互独立
        的,也就是说A模块中的全局变量和函数,B模块是无法访问的,若B模块想要使用
        A模块已有的符号,那么必须将A模块中的符号做导出,导出到模块符号表中,然后
        B模块才能使用符号表里的符号。
        3 如何做符号导出?
        linux内核给我们提供了两个宏:
        EXPORT_SYMBOL(符号名);
        EXPORT_SYMBOL_GPL(符号名);
        EXPORT_SYMBOL_GPL(gtest);
        EXPORT_SYMBOL_GPL(func);
        例如:模块A-->符号导出的模块
                hello.c-->EXPORT_SYMBOL_GPL(gtest);
                            EXPORT_SYMBOL_GPL(func);
                make成功后会生成一个存放符号的本地符号表,本地符号表中存放的就是
                代码里导出的符号
                Module.symvers:
Addr------------符号名------------模块名-------------导出符号的宏
0x8eaf8fe3    gtest    /home/farsight/2022/22101/driver/day1/module_symbol/module_exportA/hello    EXPORT_SYMBOL_GPL
0xd1a68ac8     Func    /home/farsight/2022/22091/driver/day1/module_symbol/module_exportA/hello    EXPORT_SYMBOL_GPL

                模块B--》使用导出符号的模块
                    使用条件:1 将A模块导出的符号表拷贝到B模块中
                                  2 在B模块的代码里外部声明使用哪个符号,然后才能使用
        
            测试步骤:
                1 sudo insmod hello.ko-->符号导出模块
                2 sudo insmod world.ko--》使用符号的模块
                3 dmesg |tail -->
                4 lsmod
                5 sudo rmmod world.ko
                6 sudo rmmod hello.ko

          linux内核提供了两类符号表:
        第一种:用户自定义模块导出的符号表,称为本地符号表Module.symvers
        第二种:内核全局符号表 /proc/kallsyms
            sudo cat /proc/kallsyms |grep printk
            c15cd833 T printk
            函数指针=0xc15cd833;
           int printf(const char *format,...)
    

相关文章:

基于linux内核的驱动开发学习

1 驱动 定义:驱使硬件动起来的程序 种类:裸机驱动:需求分析--》查原理图--》查芯片手册--》code 系统驱动:需求分析--》查原理图--》查芯片手册--》设备树--》code --》安装到内核中…...

python3 django gunicorn

首先,Gunicorn是一个高效的Web服务器,地位相当于Java中的Tomcat。简单来说gunicorn封装了HTTP的底层实现,我们通过gunicorn启动服务,用户请求与服务相应都经过gunicorn传输。下载gunicorn的方法也比较简单,在django工程…...

专家分享 | 租赁型售楼处标准化示范区提效研究

2023年2月8日上午,优积科技邀请原金地集团北京公司 高级室内设计专业应锎经理为我司团队分享《租赁型售楼处标准化示范区提效》的专题。 此次专家分享课题加上大家踊跃讨论时间长达3小时,会上应总详细介绍了租赁型售楼处标准化示范区提效,需…...

linux之echo使用技巧

参考文章:linux基本功系列-echo命令实战一、echo 命令是什么?作用: echo命令能将指定文本显示在Linux命令行上,或者通过重定向符写入到指定的文件中。语 法:echo [-ne][字符串] / echo [–help][–version]补充说明&am…...

Keras实例教程(7)之构建模型的第三种方式

多年以前,在TensorFlow中搭建深度学习模型对于很多人来说其实仍然是比较困难的。相比之下,Keras作为独立于TensorFlow的一种深度学习框架则要简单很多。在TensorFlow与PyTorch的竞争中逐渐式微的情况下,TensorFlow团队终于宣布Keras将成为在tensorflow2.0中构建和训练模型的…...

【JUC并发编程】18 CopyOnWriteArrayList源码也就够看2分钟

文章目录1、CopyOnWriteArrayList概述2、原理 / 源码1)构造函数2、add()3)get()4)remove()5)iterator()1、CopyOnWriteArrayList概述 CopyOnWriteArrayList相当于线程安全的ArrayList,底层是一个可变数组。 特点如下…...

如何优雅的实现回调函数?

本篇文章又是一期优雅的代码编程介绍———回调函数。 传统的nodejs编程都是这样的 const fs require(fs) fs.readFile(test.txt,utf8, function(err, dataStr){if(err){} }) 嵌套层级如果多了就成回调地狱了。如果我们将这种风格的代码转换成这样呢? const fs …...

3GPP-NR Band20标准定义频点和信道(3GPP V17.7.0 (2022-12))

Reference test frequencies for NR operating band n20 Table 4.3.1.1.1.20-1: Test frequencies for NRoperating band n20 and SCS 15 kHz CBW [MHz]carrierBandwidth...

Excel表格的公式不想显示出来,可以这样操作

在制作Excel表格的时候,很多人做数据会用到函数公式,这些编辑都是默认可以看到的。 但有时候我们不想让他人看到自己的计算思路和所用公式,有没有办法可以隐藏公式,只显示数据呢?答案是肯定的,今天我们就来…...

【零基础入门前端系列】—语义化标签、实体字符、视频、音频(八)

【零基础入门前端系列】—语义化标签、实体字符、视频、音频(八) 一、什么是HTML语义化标签 语义化的标签,旨在让标签有自己的含义 如上代码:p标签与span标签的区别之一就是,p标签的含义是段落而span标签没有独特的…...

超详细讲解线性表和顺序表!!

超详细讲解线性表和顺序表!!线性表顺序表顺序表的概念及结构静态顺序表动态顺序表顺序表接口实现1、创建2、初始化3、扩容4、尾插5、打印6、销毁7、尾删8、头插9、头删10、插入任意位置11、删除任意位置12、查找13、修改线性表 线性表(linea…...

大数据之-Nifi-Nifi的安装_启动_认识Nifi的操作台---大数据之Nifi工作笔记0002

然后我们看一下如何安装nifi 这个上一节已经说了 然后看一下环境准备,这个自己去安装就可以了,需要jdk,1.8就可以了,然后 maven安装上就可以了 然后去下载,这里下载Linux版本的 1.9.2的版本比较稳定 下载以后,避免端口冲突要修改端口默认是8080,修改为58080 然后启动很简单,看…...

【大数据clickhouse】clickhouse 常用查询优化策略详解

一、前言 在上一篇我们分享了clickhouse的常用的语法规则优化策略,这些优化规则更多属于引擎自带的优化策略,开发过程中只需尽量遵守即可,然而,在开发过程中,使用clickhouse更多将面临各种查询sql的编写甚至复杂sql的…...

【Java项目】基于Java+MySQL+Tomcat+maven+Servlet的个人博客系统的完整分析

✨哈喽,进来的小伙伴们,你们好耶!✨ 🛰️🛰️系列专栏:【Java项目】 ✈️✈️本篇内容:个人博客系统前后端分离实现! 🚀🚀个人代码托管github:博客系统源码地址&#xff…...

java 程序员怎么做找工作

java 程序员怎么做找工作 在网络招聘网站上搜索职位。在中国,像智联招聘、前程无忧、猎聘网等招聘网站上,有许多公司在招聘JAVA程序员。通过这些网站可以快速找到自己合适的工作。 关注社交媒体和专业网站。 加入一些面向JAVA程序员的社交媒体和专业网…...

S7-1200对于不同项目下的PLC之间进行开放式以太网通信的具体方法示例

S7-1200对于不同项目下的PLC之间进行开放式以太网通信的具体方法示例 如下图所示,打开TIA博途创建一个新项目,并通过“添加新设备”组态 S7-1200 客户端 ,选择 CPU1214C DC/DC/DC (client IP:192.168.0.102),建立新子网; 首先编写客户端程序:打开OB1编程界面,选择指令…...

操作系统(四):磁盘调度算法,先来先服务,最短寻道时间优先,电梯算法

文章目录一、磁盘结构二、先来先服务三、最短寻道时间优先四、电梯算法 SCAN一、磁盘结构 盘面(Platter):一个磁盘有多个盘面; 磁道(Track):盘面上的圆形带状区域,一个盘面可以有多…...

maven解决包冲突简单方式(插件maven helper | maven指令)

文章目录使用idea插件maven helper使用maven指令在Java开发中,常常会遇到不同jar包之间存在冲突的情况,这可能会导致编译错误、运行时异常等问题。 使用idea插件maven helper 在idea安装插件maven helper 安装重启完之后点击pom文件,有一个De…...

100行Pytorch代码实现三维重建技术神经辐射场 (NeRF)

提起三维重建技术,NeRF是一个绝对绕不过去的名字。这项逆天的技术,一经提出就被众多研究者所重视,对该技术进行深入研究并提出改进已经成为一个热点。不到两年的时间,NeRF及其变种已经成为重建领域的主流。本文通过100行的Pytorch…...

linux操作系统篇

目录 操作系统概述基本特征并发共享虚拟异步进程管理内存管理文件管理设备管理宏内核和微内核宏内核微内核中断分类外中断异常陷入(系统调用)进程管理进程与线程的区别进程状态切换进程调度算法**批处理系统****交互式系统**进程同步临界...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

ubuntu清理垃圾

windows和ubuntu 双系统&#xff0c;ubuntu 150GB&#xff0c;开发用&#xff0c;基本不装太多软件。但是磁盘基本用完。 1、查看home目录 sudo du -h -d 1 $HOME | grep -v K 上面的命令查看$HOME一级目录大小&#xff0c;发现 .cache 有26GB&#xff0c;.local 有几个GB&am…...