首页 > 系统相关 >linux驱动开发框架

linux驱动开发框架

时间:2024-11-18 12:14:32浏览次数:3  
标签:NAME 框架 xxx MODULE COMMITID module linux 驱动 hello

前言

一、环境搭建

不同系统不一样,需要安装内核的开发包,下面是kali linux的方式,里面的版本号使用uname -r确认

sudo apt install linux-image-6.11.2-amd64-dbg linux-headers-6.11.2-amd64

二、开发指导

1. 基本模板

1.1. Makefile编写

  • Makefile第一个M要大写,不然也会报错
NAME := hello

obj-m := $(NAME).o

ifeq ($(KERNDIR), )
KDIR := /lib/modules/$(shell uname -r)/build
else
KDIR := $(KERNDIR)
endif
PWD := $(shell pwd)

$(NAME)-obj += hello_main.o

# $(NAME)-y +=
# $(NAME)-n +=

ifeq ($(DEBUG), 1)
ccflags-y += -g -O0
endif

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean :
	$(MAKE) -C $(KDIR) M=$(PWD) modules clean
1) 命令解释
  • linux驱动编译最核心的命令是make -C <kernel-source-dir> M=$(PWD) modules
  • -C <dir>: 指定内核源码目录,里面存放最高级的makefile
  • M=<dir>: 代表我们模块的makefile在这里
2) Makefile内容解释
  • obj-m := ${MODULE_NAME}.o: 指定要编译的ko文件,${MODULE_NAME}.o会生成${MODULE_NAME}.ko文件,写多个会生成多个
  • ${MODULE_NAME}-obj += xxx.o: 指定要编译的多个c文件,每个xxx.o会找xxx.c文件去编译,注意不能和${MODULE_NAME}同名,同名会循环引用错误
    • 如果编译hello.ko有两个源文件hello.cfile1.c,需要指定obj-m := hello.o,而obj需要将hello.c重命名为hello_main.c,然后设置hello-objs := hello_main.o file1.o
    • 如果只有一个源文件hello.c,那么不用指定hello-objs,会找hello.c文件
    • 经过测试,此变量不能等于变量,需要显式指定文件
  • ${MODULE_NAME}-y += xxx.o: 和-n对应,某些文件是否编译进去,一般设定变量来决定是y还是n

1.2. 源文件结构

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL");
static int hello_init(void) {
    printk(KERN_ALERT "hello, world\n");
    return 0;
}

static void hello_exit(void) {
    nf_unregister_net_hook(&init_net, &nfho);
    printk(KERN_ALERT "Goodby, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);
  • 上面这样的结构,需要用module_initmodule_exit定义insmod和rmmod对应的时间点的操作
  • 打印只能使用printk,会输出到dmesg命令的输出中
  • MODULE_LICENSE定义开源协议

2. 传参

  • 源文件中这样写可以传参
static int mode = 0;                    // 这里定义默认值
module_param(mode, int, S_IRUGO);       // 第三个参数是权限,定义在include/linux/stat.h,这里是0444

传参示例

# 驱动传参必须指定参数名称
insmod ./aaa.ko mode=1

权限的作用

  • 所有挂载的驱动,在/sys/module/<mod_name>/parameters/下以参数名命名
=> ls -l /sys/module/test/parameters/
total 0
-r--r--r-- 1 admin root 4096 Mar 26 11:21 mode
=> cat /sys/module/test/parameters/mode
1
  • 权限设置为可写的话,其实可以使用vi进行修改此选项。但是内核没有方式通知驱动此参数值发生了变化,所以要么自己写机制保障,要么就权限设置为只读

三、小工具代码

1. 日志

#include <linux/printk.h>

#define tag "xxx"

#define xxx_log_info(fmt, ...) \
    pr_info("[%s] "fmt, tag, ##__VA_ARGS__)

2. 编译的内核版本输出

  • 这个只输出针对编译内核的版本
#include <linux/version.h>

static char *get_kernel_version(void) {
    static char buf[16] = {0};
    short a, b, c;

    if (buf[0] != 0) return buf;

    a = LINUX_VERSION_CODE >> 16;
    b = (LINUX_VERSION_CODE >> 8) & 0xff;
    c = LINUX_VERSION_CODE & 0xff;
    sprintf(buf, "%d.%d.%d", a, b, c);
    return buf;
}

3. 添加git commitid

makefile中对于编译添加选项

ifeq ($(GIT_COMMITID), )
GIT_COMMITID := $(shell git rev-parse HEAD)
endif

ccflags-y += -DGIT_COMMITID=\"$(GIT_COMMITID)\"

代码中定义到comment里面

#ifndef GIT_COMMITID
#define GIT_COMMITID "unknown"
#endif

// 显示在modinfo xxx.ko中
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("xxxx, Git: "GIT_COMMITID);

标签:NAME,框架,xxx,MODULE,COMMITID,module,linux,驱动,hello
From: https://blog.csdn.net/qq_26124425/article/details/143821512

相关文章

  • Linux :进程间通信之管道
    一、进程间通信1.1是什么和为什么1、进程间通信是什么??——>两个或多个进程实现数据层面的交互,但是由于进程独立性的存在,导致通信的成本比较高。2、既然通信成本高,那为什么还要通信呢??——> 在某些场景下我们需要不同进程之间进行(1)基本数据的交互。(2)发送命令。(3)实现某种......
  • linux 安装 docker
    安装yum-utilsyuminstall-yyum-utils\device-mapper-persistent-data\lvm2--skip-broken执行如果报错Cannotfindavalidbaseurlforrepo:base/7/x86_64解决办法编辑/etc/yum.repos.d/CentOS-Base.repo[base]name=CentOS-$releaseve......
  • Java集合框架、集合工具类Collections、泛型 ;代码之滑动窗口总结(11.15)
    Java基础学习迭代器1、迭代器的指针一开始在集合的上方next():指针下移,下移以后返回指针指向的值2、使用迭代器遍历集合元素 //正确写法Iteratoriterator=coll.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}//错误写法,......
  • linux 下安装 jdk
    linux下安装jdk-11----1----https://download.oracle.com/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz解压安装包tar-xvfopenjdk-11.0.2_linux-x64_bin.tar.gz或tar-xzvfjdk-11.0.23_linux-x64_bin.tar.gz编辑profile文件vim/etc/profileJAVA_HOME=......
  • 基于Netty框架的云快充协议+云快充协议1.5+桩直连协议+充电桩系统
    云快充协议+云快充1.5协议+云快充1.6+云快充协议开源代码+云快充底层协议+云快充桩直连+桩直连协议+充电桩协议+云快充源码介绍云快充协议+云快充1.5协议+云快充1.6+云快充协议开源代码+云快充底层协议+云快充桩直连+桩直连协议+充电桩协议+云快充源码软件架构1、提供云快......
  • 低成本玩转Linux开发板(基于NUC980双层板)原理图+PCB分享
    更多电路设计,PCB设计分享及分析,可关注本人微信公众号“核桃设计分享”!由于公司项目需求,一直在找一款能跑Linux系统,外围接口丰富的,关键是必须要有CAN,UART,RMII等接口的芯片(无需LCD,HDMI,eDP)。对于一般的多媒体芯片来说,类似于瑞芯微,全志,海思,NXP等方案上,基本都是BGA封装的居多,CAN......
  • linux常用命令有哪些?
    在Linux中,常用命令有很多,主要包括文件管理、系统管理、网络配置、用户管理等方面。以下是一些常见的Linux命令及其功能:1.文件和目录管理ls列出当前目录下的文件和子目录。常用选项:-l:长格式显示详细信息-a:显示所有文件,包括隐藏文件-h:以人类可读的格式显示文件大小(如K......
  • 70.Linux虚拟机网络有关配置总结
    这个Java开发怎样都绕不开虚拟机服务端的理解学习当初都是模棱两可的学习现在总是要总结的首先如果你的ens33无出现那种什么service开启了还有啥虚拟网卡都开启了大致就简单还原一些默认设置就好了当然还有一种可能就是我当初总结过的https://www.cnblogs.com/gaodiyu......
  • HarmonyOS Next 加解密算法框架入门:基础概念与功能概述
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。一、引言在当今数字化时代,信息安全犹......
  • Linux:外观数列
    给定一个正整数n(1≤n≤30),输出外观数列的第n项。注意:整数序列中的每一项将表示为一个字符串。「外观数列」是一个整数序列,从数字1开始,序列中的每一项都是对前一项的描述。前五项如下:111211211111221第一项是数字1描述前一项,这个数是1即“一个1”,记作11......