linux 模块安装与卸载

文章目录

    • 模块实现
    • 编译模块的 makefile
    • 编译报错解决
    • 模块编译日志
    • 自动化
    • 模块安装
    • 模块卸载
    • 配置头文件路径
      • C/C++ 插件
      • clangd 插件

模块实现

新建 my_module.c 文件

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>static int __init module_base_init(void)
{printk("base module init!\r\n");return 0;
}static void __exit module_base_exit(void)
{printk("base module exit!\r\n");
}module_init(module_base_init);
module_exit(module_base_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("tyustli");

编译模块的 makefile

新建 Makefile 文件

# 指定内核路径
KERNELDIR := /home/tyustli/code/open_source/kernel/linux-6.5.7
# 指定当前路径
CURRENT_PATH := $(shell pwd)
# 指定编译的模块名
obj-m := my_module.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

编译报错解决

此时如果直接在模块路径执行 make 会有 如下警告和报错,cc1: error: cannot load plugin ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: undefined symbol: _Z16gen_load_tp_hardP7rtx_def

完整日志如下

make -C /home/tyustli/code/open_source/kernel/linux-6.5.7 M=/home/tyustli/code/qemu_code/linux_driver/0001_module_init modules
make[1]: Entering directory '/home/tyustli/code/open_source/kernel/linux-6.5.7'
warning: the compiler differs from the one used to build the kernelThe kernel was built by: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621You are using:           gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0CC [M]  /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.o
cc1: error: cannot load plugin ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: undefined symbol: _Z16gen_load_tp_hardP7rtx_def
make[3]: *** [scripts/Makefile.build:243: /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.o] Error 1
make[2]: *** [/home/tyustli/code/open_source/kernel/linux-6.5.7/Makefile:2037: /home/tyustli/code/qemu_code/linux_driver/0001_module_init] Error 2
make[1]: *** [Makefile:237: __sub-make] Error 2
make[1]: Leaving directory '/home/tyustli/code/open_source/kernel/linux-6.5.7'
make: *** [Makefile:11: kernel_modules] Error 2

这是因为前面编译内核的时候 ARCHCROSS_COMPILE 是通过 shell 脚本传进去的,编译模块的时候又没有指定这些。

解决方法就是在内核顶层的 Makefile 直接定义这两个变量(有点粗暴)

ARCH = arm
CROSS_COMPILE = arm-none-linux-gnueabihf-

在这里插入图片描述

模块编译日志

make -C /home/tyustli/code/open_source/kernel/linux-6.5.7 M=/home/tyustli/code/qemu_code/linux_driver/0001_module_init modules
make[1]: Entering directory '/home/tyustli/code/open_source/kernel/linux-6.5.7'CC [M]  /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.oMODPOST /home/tyustli/code/qemu_code/linux_driver/0001_module_init/Module.symversCC [M]  /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.mod.oLD [M]  /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.ko
make[1]: Leaving directory '/home/tyustli/code/open_source/kernel/linux-6.5.7'

在这里插入图片描述

自动化

模块编译好之后,最好的方法就是将 rootfs 设置为 nfs,这样直接将编译的 ko 放到网络文件系统中,直接启动内核即可。

由于目前使用的是 ubuntu + wifi 的形式,如果想让 qemu 联网,需要建立网桥,但是 wifi 网卡没有处于 AP 模式,处于 Managed 模式的无线网卡没有足够多的信息做网桥,只能转换成 master 模式

iwconfig wlp2s0 mode master

结果网卡不支持

Error for wireless request "Set Mode" (8B06) :SET failed on device wlp2s0 ; Operation not permitted.

只能通过软件 hostapd 来实现。。。。。。

这个有点复杂,超出了研究 linux driver 的目的。

解决方法就是,每次生成 xxx.ko 之后,将生成的 ko 文件拷贝到根文件目录下,然后重新打包 rootfs 根文件系统。这样 linux 启动之后模块就在 rootfs 根文件系统中

# 将生成的 .ko 文件拷贝到根文件系统的 roorfs 中
cp ./my_module.ko /home/tyustli/code/open_source/busybox/rootfs/dev# 切换到根文件系统目录
cd /home/tyustli/code/open_source/busybox
# 生成虚拟 SD 卡系统镜像
sudo dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
# 格式化镜像
sudo mkfs.ext3 rootfs.ext3#将文件复制到镜像中
sudo mkdir tmpfs_rootfs
sudo mount -t ext3 rootfs.ext3 tmpfs_rootfs/ -o loop
sudo cp -r rootfs/*  tmpfs_rootfs/
sudo umount tmpfs_rootfs
rmdir tmpfs_rootfs

这里 rootfs 就制作好了,重新启动 linux

sudo qemu-system-arm -M vexpress-a9 -m 512M \
-kernel /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/zImage \
-dtb /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb -nographic \
-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
-sd /home/tyustli/code/open_source/busybox/rootfs.ext3

脚本源码

#                          参数解析
# ./my_module_build.sh      para1            para2(可选)
#   脚本名称            指定模块路径     是否执行 make clean 命令# 判断 shell 脚本有几个参数,如果没有指定 module 目录, shell 脚本就报错退出
if [ $# -eq 0 ]; thenecho "Incorrect number of arguments for command
Usage: my_module_build.sh <module_dir>  build your own module"exit
fi# 切换到指定的目录
cd $1# 如果是清除工程,就执行 make clean 命令
if [ "$2" == "clean" ]; thenmake cleanexit
fi# 编译指定目录的模块
make
# 将生成的 .ko 文件拷贝到根文件系统的 roorfs 中
cp ./my_module.ko /home/tyustli/code/open_source/busybox/rootfs/dev# 切换到根文件系统目录
cd /home/tyustli/code/open_source/busybox
# 生成虚拟 SD 卡系统镜像
sudo dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
# 格式化镜像
sudo mkfs.ext3 rootfs.ext3#将文件复制到镜像中
sudo mkdir tmpfs_rootfs
sudo mount -t ext3 rootfs.ext3 tmpfs_rootfs/ -o loop
sudo cp -r rootfs/*  tmpfs_rootfs/
sudo umount tmpfs_rootfs
rmdir tmpfs_rootfs# 切换回指定的目录
cd $1# 启动 kernel
sudo qemu-system-arm -M vexpress-a9 -m 512M \
-kernel /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/zImage \
-dtb /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb -nographic \
-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
-sd /home/tyustli/code/open_source/busybox/rootfs.ext3

用法

./my_module_build.sh 0001_module_init/

模块安装

查看模块文件是否存在

ls /dev/my_module.ko 

模块安装

/dev/my_module.ko

在这里插入图片描述
base module initmodule_base_init 打印的信息一致

模块卸载

rmmod my_module

在这里插入图片描述
base module exitmodule_base_exit 打印的信息一致

配置头文件路径

my_module.c 文件中使用 #include 包含了一些内核的头文件,那么这些头文件如何跳转可以借助 C/C++ 插件,或者 clangd 插件

C/C++ 插件

Ctrl + Shift + p 输入 C/C++:Edit Configurations(JSON),在当前路径下会自动新建一个 .vscode 文件,并生成 c_cpp_properties.json,在文件中输入

{"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**","/home/tyustli/code/open_source/kernel/linux-6.5.7/include","/home/tyustli/code/open_source/kernel/linux-6.5.7/include/uapi","/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include","/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include/generated","/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include/generated/uapi"],"defines": [],"compilerPath": "/home/tyustli/cross_tool/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc","cStandard": "c17","cppStandard": "gnu++17","intelliSenseMode": "linux-gcc-arm"}],"version": 4
}

这样配置之后头文件可以正常跳转

同样可以在 .vscode 生成 settings.json 文件,在其中输入

{"search.exclude": {"**/node_modules": true,"**/bower_components": true,"**/*.su":true,"Documentation":true,},"files.exclude": {"**/.git": true,"**/.svn": true,"**/.hg": true,"**/CVS": true,"**/.DS_Store": true,"**/*.su":true,"Documentation":true,},"files.associations": {"map.h": "c","module.h": "c","init.h": "c","types.h": "c","kernel.h": "c","kobject.h": "c","sysfs.h": "c","kernfs.h": "c","idr.h": "c","radix-tree.h": "c","xarray.h": "c","mm.h": "c","sched.h": "c","seccomp.h": "c","*.tcc": "c","compiler_attributes.h": "c"}
}

clangd 插件

使用下面命令生成 compile_commands.json 文件

bear -- make

配置 clangd,由于 clangd 和 c/c++ 会存在冲突,在 settings.json

    "C_Cpp.intelliSenseEngine": "disabled",

配置 c_cpp_properties.json 文件

"compileCommands": "${workspaceFolder}/linux_driver/0001_module_init/compile_commands.json"

最终会生成一个 .cache 目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/174582.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter报错RenderBox was not laid out: RenderRepaintBoundary的解决方法

文章目录 报错问题分析问题原因 解决办法RenderBox was not laid out错误的常见原因常见原因解决方法 RenderRepaintBoundaryRenderRepaintBoundary用途 报错 RenderBox was not laid out: RenderRepaintBoundary#d4abf relayoutBoundaryup1 NEEDS-PAINT NEEDS-COMPOSITING-BI…

海南海口大型钢结构件3D扫描全尺寸三维测量平面度平行度检测-CASAIM中科广电

高精度三维扫描技术已经在大型工件制造领域发挥着重要作用&#xff0c;特别是在质量检测环节&#xff0c;高效、高精度&#xff0c;可以轻松实现全尺寸三维测量。本期&#xff0c;CASAIM要分享的应用是在大型钢结构件的关键部位尺寸及形位公差检测。 钢结构件&#xff0c;是将…

功能型前端项目技术栈选型

PC功能型官网技术栈选择 vue2vuexvue-routerxaxiosanimate主推&#xff1a;vue3piniavue-routertypeScriptaxiosanimate&#xff08;新技术后期踩坑多&#xff0c;成本较高&#xff09; 1.2 vue3对比vue2 团队已经熟悉 Vue 2&#xff0c;并且官网的规模不是很大&#xff0c;Vue…

使用 Visual Studio Code 编写 TypeScript程序

安装 TypeScript 首先&#xff0c;确保你已经安装了 TypeScript&#xff0c;如果没有安装&#xff0c;请参考https://blog.csdn.net/David_house/article/details/134077973?spm1001.2014.3001.5502进行安装 创建 新建一个文件夹&#xff0c;用vs code打开&#xff0c;在文…

【MySQL--->内外连接】

文章目录 [TOC](文章目录) 一、内连接二、左外连接三、右外连接 一、内连接 内连接就是将两个表连接进行笛卡尔积查询 显示SMITH的名字和部门名称 二、左外连接 左外连接就是以左面的表为主&#xff0c;即便是右边的表没有而左边表项中有的&#xff0c;依然显示 查询所有学…

C# “依赖注入” 中的 “三种生命周期”

&#x1f680;简介 依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;是一种实现控制反转&#xff08;IoC&#xff09;的技术&#xff0c;用于减少代码之间的耦合度。通过依赖注入&#xff0c;一个类可以从外部获取其依赖的对象&#xff0c;而不是自己…

评估在线不平衡学习的PAUC

评估在线不平衡学习的PAUC 原始论文《Prequential AUC: properties of the area under the ROC curve for data streams with concept drift》 由于正常的AUC需要计算整体数据集上&#xff0c;每个数据的预测置信度的排名。那么我们首先要求我们的在线学习算法在进行预测时也返…

实体店做商城小程序如何

互联网电商深入各个行业&#xff0c;传统线下店商家无论产品销售还是服务业&#xff0c;仅靠以往的经营模式&#xff0c;很难拓展到客户&#xff0c;老客流失严重&#xff0c;同时渠道单一&#xff0c;无法实现外地客户购物及线上客户赋能等。 入驻第三方平台有优势但也有不足…

审核 Microsoft SQL Server 日志

手动审核数据库活动是一项艰巨的任务&#xff0c;有效完成审计的最佳方法是使用简化和自动化数据库监控的综合解决方案&#xff0c;该解决方案还应使数据库管理员能够监控、跟踪和即时识别任何操作问题的根本原因&#xff0c;并实时检测对机密数据的未经授权的访问。 什么是 S…

Java on Azure Tooling 9月更新|Azure OpenAI 服务和 Playground 支持及更多

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 开发者工具九月份更新。在本次更新中&#xff0c;我们将介绍对 Azure OpenAI 服务和 Playground 的支持&#xff0c;开发…

<C++> vector模拟实现

目录 前言 一、定义命名空间 二、构造函数 三、拷贝构造 四、赋值运算符重载 五、push_back && reserve 六、深拷贝问题 七、iterator 迭代器 1. 可读可写 2. 只读 八、operator[ ] 1. 可读可写 2. 只读 九、insert 问题&#xff1a;内部迭代器失效 十、erase 十一、re…

《RT-DETR改进实战》专栏介绍 专栏目录

《RT-DETR改进实战专栏》介绍及目录 介绍&#xff1a;欢迎来到最新专栏《RT-DETR改进实战》&#xff01;这个专栏专注于基于 YOLOv8 项目的魔改版本&#xff0c;而不是百度飞桨框架中的 RT-DETR。 本专栏为想通过改进 RT-DETR 算法发表论文的同学设计。每篇文章均包含完整的改…

探讨下前端测试的常见场景

前端测试 场景 这边指的测试是指白盒测试&#xff0c;用代码来测试代码。 测试有利于提升代码质量。 代码功能和需求一致。根据需求&#xff0c;写测试。测试通过了&#xff0c;则表明需求实现了。保证代码重构后&#xff0c;未改坏以前的功能。代码重构后&#xff0c;能通过…

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.M…

jenkins详细安装教程

这里写目录标题 一、Jenkins安装与部署1-1、Jenkins的简介1-2、下载需要的软件1-2-1 jekins.war1-2-2 tomcat安装方式 1-3、使用11版本的jdk1-4、开启jenkins1-5、获取密码1-5 修改镜像(可改可不改) 二、卸载Jenkins 一、Jenkins安装与部署 1-1、Jenkins的简介 Jenkins是一个…

Java电商平台 - API 接口设计之 token、timestamp、sign 具体架构与实现|电商API接口接入

一&#xff1a;token 简介 Token&#xff1a;访问令牌access token, 用于接口中, 用于标识接口调用者的身份、凭证&#xff0c;减少用户名和密码的传输次数。一般情况下客户端(接口调用方)需要先向服务器端申请一个接口调用的账号&#xff0c;服务器会给出一个appId和一个key, …

mysql 间隙锁

mysql 默认是可重复读的隔离级别&#xff0c;这种默认会有幻读&#xff0c;幻读指的什么现象呢&#xff0c;就是在同一个事物中前后两次查到的结果不一致&#xff0c;那么mysql是怎么解决幻读的呢&#xff0c;这就是mvcc mvcc 什么是mvcc呢&#xff0c;就是多版本并发控制&am…

迁移学习 - 微调

什么是与训练和微调&#xff1f; 你需要搭建一个网络模型来完成一个特定的图像分类的任务。首先&#xff0c;你需要随机初始化参数&#xff0c;然后开始训练网络&#xff0c;不断调整参数&#xff0c;直到网络的损失越来越小。在训练的过程中&#xff0c;一开始初始化的参数会…

【Python算法】算法练习(一)

❤️博客主页&#xff1a; iknow181 &#x1f525;系列专栏&#xff1a; Python、JavaSE、JavaWeb、CCNP &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐评论✍ 目录 1、输出n以内的质数 2、求n以内最大的m个质数的和&#xff0c;并打印这些质数以及它们的和 方法一 方法二…

GaussDB数据库管理系统介绍

1.GaussDB的发展 2.GaussDB的生态 内部&#xff1a; 云化自动化方案。通过数据库运行基础设施的云化将DBA(数据库管理员)和运维人员的日常工作 自动化。外部&#xff1a; 采用与数据库周边生态伙伴对接与认证的生态连接融合方案&#xff0c;解决开发者/DBA难获取、应用难对接等…