关于如何在Arch Linux上编写自己的第一个module

        前一段时间一直想深入学习编写一个module插入到自己的内核当中,但是网上的资料基本上全都针对的Ubuntu和Debian等流行的Linux发行版,这里打算简单的记录一波博客。

啥是Module?(着急可不看)

        众所周知:现代宏内核架构的操作系统都会借鉴微内核当中比较有价值的设计思想,这里的modules正是“模块”的意思,模块模块,可载可拆。他的加载和卸载是动态的,我们并不需要重新编译内核,只需要使用insmod和rmmod指令,就可以加载或者卸载自己的module。

        模块的文件后缀是.ko文件,也是我们编程到最后生成的目标文件,挂载与卸载的就是.ko文件。(熟悉Linux内核编程的同志可以一眼认出这是kernel object的缩写)

正题:如何编写自己的kernel module

        模块的编写方式同一般的写法有些区别,作为对比,我们给出一个例子:

// 我们编写基础的模块需要这三位兄第
#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>// 模块谁写的?
MODULE_AUTHOR("Charliechen");
// 模块的认证签名协议是?
MODULE_LICENSE("GPL");// 下面开始是程序的正文。有同志会好奇干嘛是static呢?原因很简单:
// 模块的加载是独立的,作为下面即将使用的加载模块和卸载模块的函数,我们只会在
// 自己的文件中使用,因此!加上static,告知gcc不需要跑去找声明
static int prt_times = 10;static int __init Charliechen_init(void){for(int i = 0; i < prt_times; i++)printk("SUP, DUDE!");return 0;
}static void __exit Charliechen_exit(void){printk("GOODBYE_BOY");
}module_init(Charliechen_init);
module_exit(Charliechen_exit);

        你会很懵,这个结构跟我们所熟悉的模块编程完全不一样!多了很多陌生的东西。如果你现在只是想快速的跳到结果,可以前往下一个小节了。

static int __init Charliechen_init(void){for(int i = 0; i < prt_times; i++)printk("SUP, DUDE!");return 0;
}// ... omitted ...module_init(Charliechen_init);

       首先是模块的初始化函数,当我们的模块加载程序运行的时候,他会调用我们被标注以:module_init包裹的函数,这个函数将会作为我们对模块的初始化的函数,借用一下面对对象编程的术语,那就是构造函数!

        很简单这个函数做的事情:无非就是向内核打印"Sup, Dude"10次,很简单是吧。那么,这个__init做什么事情呢?学过内核编程的都知道这是标记符号:在这里,gcc扫描到__init这个东西,就会把这个函数放到特别安排的区域,同理,__exit也是!好了,我们最后使用module_init或者是module_exit函数(咱们是动态加载)声明我们的“构造”函数和“析构函数”就好。

撸Makefile

        是的,我们生成模块要使用Makefile去写,先给出Makefile

# 最后生成的模块名称的模块重定位文件
#(实际上就是说自己.ko的前面是啥,这里需要跟源文件名称一致)
obj-m:= charlie.o 
pwd:= $(shell pwd) # 当前目录
KDIR:= /lib/modules/($shell uname -r)/build # 我们的Kernel modules依赖文件在哪里# make执行的:
all:make -C $(KDIR) M=$(pwd) modules# make clean执行的
clean:rm -rf *.o .* .cmd *.ko *.mod.c .tmp_versions *.order *.symvers *.mod

        有同志马上就会发现自己没有/lib/modules/(uname -r)/build这个文件夹,这个需要单独下载:yay -Ss linux-headers,确认包的名称跟自己的linux-header一致后,下载下来,你就会发现多了一个build文件夹,里面就是我们开发modules的SDK了!

        我们下面make

➜  make
make -C /lib/modules/6.9.3-arch1-1//build M=/home/Charliechen/Works/opearte_system/module modules
make[1]: 进入目录“/usr/lib/modules/6.9.3-arch1-1/build”CC [M]  /home/Charliechen/Works/opearte_system/module/charlie.oMODPOST /home/Charliechen/Works/opearte_system/module/Module.symversCC [M]  /home/Charliechen/Works/opearte_system/module/charlie.mod.oLD [M]  /home/Charliechen/Works/opearte_system/module/charlie.koBTF [M] /home/Charliechen/Works/opearte_system/module/charlie.ko

        好了,我们拿到了自己的module了,下面讲解如何挂载,查看信息,卸载。

挂载我们的module

        挂载模块很简单:

sudo insmod 模块名.ko

        我先前踩过这个坑:

ERROR: Can not load xxx.ko: Invalid Format

        排查一下,会告知你很具体的原因,办法是:

dmesg | tail -2

        最常见的原因是模块的系统版本签名和自己将要挂载的系统的版本不对等,arch兄弟们可以reboot(大概率是自己update系统之后不reboot导致自己使用的SDK版本和系统不对等),重启后保证自己的uname -r跟自己的模块系统版本签名一致就行

        正常的现象是:啥也没有

        现在,我们来看看自己的模块挂没挂上

[    6.058570] loop: module loaded
[  156.245140] charlie: loading out-of-tree module taints kernel.
[  156.245148] charlie: module verification failed: signature and/or required key missing - tainting kernel 
不用害怕最后一行,这是我们没有验证模块,不影响什么

       printk函数是内核打印函数,系统的日志就是依靠这个函数完成的,我们观察我们的模块现象:

[  156.245140] charlie: loading out-of-tree module taints kernel.
[  156.245148] charlie: module verification failed: signature and/or required key missing - tainting kernel
[  156.245609] SUP, DUDE!
[  156.245611] SUP, DUDE!
[  156.245611] SUP, DUDE!
[  156.245612] SUP, DUDE!
[  156.245612] SUP, DUDE!
[  156.245613] SUP, DUDE!
[  156.245613] SUP, DUDE!
[  156.245614] SUP, DUDE!
[  156.245614] SUP, DUDE!

       符合我们的预期:向内核打印!(吞了一个输出,无伤大雅)

查看我们module信息

        查看的办法是

modinfo xxx.ko
➜  modinfo charlie.ko
filename:       /home/Charliechen/Works/opearte_system/module/charlie.ko
license:        GPL
author:         Charliechen
srcversion:     D2FFFA830F5695951FAAC09
depends:        
retpoline:      Y
name:           charlie
vermagic:       6.9.3-arch1-1 SMP preempt mod_unload 

卸载我们的module

sudo rmmod xxx.ko 
[  952.395595] GOODBYE_BOY

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

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

相关文章

vcruntime140.dll丢失如何安装,附找不到vcruntime140.dll的六种解决方法

vcruntime140.dll是一个动态链接库文件&#xff0c;属于Microsoft Visual C Redistributable Packages的一部分&#xff0c;专为Visual Studio 2015开发环境设计。它提供了C运行时库&#xff08;CRT&#xff09;中的一些关键功能&#xff0c;以及一些额外的Microsoft特定的运行…

Java排序算法汇总篇,八种排序算法

排序算法汇总: Java排序算法(一)&#xff1a;冒泡排序 Java排序算法(二)&#xff1a;选择排序 Java排序算法(三)&#xff1a;插入排序 Java排序算法(四)&#xff1a;快速排序 Java排序算法(五)&#xff1a;归并排序 Java排序算法(六)&#xff1a;希尔排序 Java排序算法(…

18.Redis之哨兵

1.哨兵机制的介绍 通过自动化的手段,来解决主节点挂了的问题~~ 哨兵机制, 是通过独立的 进程 来体现的.和之前 redis-server 是不同的进程!! redis-sentine| 不负责存储数据,只是对其他的 redis-server 进程起到监控的效果~~ 通常哨兵节点,也会搞一个集合~~(多个哨兵节点构成的…

【Pr学习】01新建项目起步

【Pr学习】01新建项目起步 1、新建项目2.序列设置2.1新建序列2.2序列参数讲解2.3自定义设置 3.PR窗口认识3.1 项目窗口3.2 源窗口2.4 保存面板 4.剪辑导入4.1 素材导入4.2 视图切换4.3 时间轴4.4轨道工具4.5 节目窗口素材导入 5.基础操作5.1 取消视频音频链接5.2 单独渲染&…

Qos令牌桶算法:笔记0601

令牌桶 令牌&#xff1a;目前看到2种表述&#xff0c;csdn表示一个令牌代表一个字节&#xff0c;51cto是一个令牌代表一个bit。51cto上关于cisco qos算法描述多表达为一个令牌一个bit (不知道rfc上咋表达的懒得去查了&#xff0c;主打一个好读书不求甚解&#xff0c;感觉应该是…

[无监督学习] 11.详细图解LSA

LSA LSA&#xff08;Latent Semantic Analysis&#xff0c;潜在语义分析&#xff09;是一种自然语言处理技术。作为一种降维算法&#xff0c;它常被用于信息搜索领域。使用 LSA 能够从大量的文本数据中找出单词之间的潜在关联性。 概述 LSA 是在 1988 年被提出的算法&#xff…

AI产品导航站

1、AI产品导航站 (chat2ai.cn)

更新mirh connect 内置derby数据库密码

更新mirh connect 内置derby数据库密码 1、下载derby连接客户端 https://archive.apache.org/dist/db/derby/ 选择任意版本即可&#xff0c;比如 https://archive.apache.org/dist/db/derby/db-derby-10.14.2.0/db-derby-10.14.2.0-bin.zip 2、连接mirh文件数据库 1、把mi…

UnityAPI学习之游戏物体的方法使用

目录 游戏物体 创建游戏物体的三种方式 组建的获取和查找 游戏物体的方法与其他成员变量 游戏物体的生成 游戏物体的激活状态/标签(tag)/层级(layer) 游戏物体的激活与失活 游戏物体的查找 1. 名称查找(Find) 2. 通过标签查找游戏物体&#xff08;FindGameObjectWithT…

关于linux程序的查看、前台运行、后台运行、杀死的管理操作。

前言 在Linux中&#xff0c; 程序&#xff08;program&#xff09;是放在磁盘上的程序&#xff0c;是不会执行的。 进程&#xff08;process&#xff09;是程序被触发&#xff0c;从而加载到内存中的&#xff0c;会被CPU随机执行。 Linux中&#xff0c;有非常多的进程在实时运…

如何让Google收录网页?

确保网页被Google快速且持续地收录&#xff0c;页面的质量起着至关重要的作用。高质量的网页不仅更容易被搜索引擎收录&#xff0c;而且能够提高网页在搜索结果中的排名&#xff0c;想确保页面的质量&#xff0c;要保持原创&#xff0c;确保你的内容是独一无二的&#xff0c;别…

Python基础教程——数据类型和变量

数据类型和变量 Python使用缩进来组织代码块,一般使用4个空格的缩进.使用#来注释一行,其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块.Python对大小写敏感. 1.1 整数 Python可以处理任意大小的整数,包括负整数,写法与数学上写法一致,例如&#xff1a;-10…

Qt Creator中, ui设计中设置属性无效, 会自动变回去问题

最近学qt遇到个问题, 很奇怪, 具体表现为: 我想修改这个字体大小为12, 但是修改后会自动变回9, 我读取qss方式设置样式, 依然无效&#xff01;找了很久&#xff0c;最终发现是我在最上层设置了字体大小&#xff0c; 导致下面的所有控件&#xff0c; 全部设置字体无效&#xff…

【CPP】栈简介及简化模拟实现

CPP栈和队列简单模拟实现 目录 1. 栈的简介2. 栈简化模拟实现3. 栈练习题 1. 栈的简介 栈 是一种 特殊的线性表&#xff0c;具有数据 先进后出 特点。 具体参考&#xff1a;【数据结构】栈 CPP库参考文档&#xff1a;stl_stack 注意&#xff1a; 1.stack本身 不支持迭代器操…

骨传导耳机防踩雷秘诀是什么?六大选购技巧独家揭秘!

相信大家都已经深有体会&#xff0c;拿那种常规的入耳式无线蓝牙耳机来做运动耳机&#xff0c;很难满足运动需要。如果选择前两年流行的颈挂式无线运动蓝牙耳机&#xff0c;虽然简单轻巧&#xff0c;但也是入耳式设计&#xff0c;长时间佩戴耳朵不舒服。这样看来&#xff0c;运…

Python-3.12.0文档解读-内置函数sorted()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 Python-3.12.0文档解读详细说明 功能描述 参数说明 用法示例 备注 进阶用法 参考…

【Qt】【模型视图架构】代理模型示例

文章目录 1. 基本排序/过滤模型Basic Sort/Filter Model Example2. 自定义排序/过滤模型Custom Sort/Filter Model ExampleFilterLineEdit类定义及实现MySortFilterProxyModel类定义及实现 1. 基本排序/过滤模型Basic Sort/Filter Model Example 官方提供的基本排序/过滤模型示…

【算法】贪心算法——柠檬水找零

题解&#xff1a;柠檬水找零(贪心算法) 目录 1.题目2.题解3.参考代码4.证明5.总结 1.题目 题目链接&#xff1a;LINK 2.题解 分情况讨论 贪心算法 当顾客为5元时&#xff0c;收下当顾客为10元时&#xff0c;收下10元并找回5元当顾客为20元时&#xff0c;收下20元并找回10…

大泽动力车载柴油发电机的特点和优势有哪些

大泽动力车载柴油发电机具有一系列显著的特点和优势&#xff0c;以下是对其的详细介绍&#xff1a; 低噪音性能&#xff1a;大泽动力车载柴油发电机具备明显的低噪音性能&#xff0c;其噪音限值在距离机组7米处测得为70dB(A)&#xff0c;这为用户提供了一个相对安静的工作环境…

Java18+​App端采用uniapp+开发工具 idea hbuilder智能上门家政系统源码,一站式家政服务平台开发 家政服务(师傅端)介绍

Java18​App端采用uniapp开发工具 idea hbuilder智能上门家政系统源码&#xff0c;一站式家政服务平台开发 家政服务&#xff08;师傅端&#xff09;介绍 家政服务师傅端是一个专为家政服务人员设计的平台&#xff0c;该平台旨在提供便捷、高效的工作机会&#xff0c;同时确保…