内核模块(.ko) 开发入门
内核模块时指的是在操作系统内核中动态加载的一段代码,它可以扩展和增强操作系统的功能。内核模块通常用于为操作系统添加新的设备驱动程序、文件系统、网络协议栈等功能。
内核模块是以二进制形式存在的(*.ko),它们被编译为对象文件,并在运行时被加载到操作系统内核中。内核模块与操作系统内核紧密耦合,可以访问内核的数据结构、函数和服务,并与操作系统的其他部分进行交互。
如何开发一个可在运行时动态加载的内核模块?下面是一个 hello world.ko 的完整实例。
1 程序实例
#include <linux/module.h>
static int hello_init(void) {
printk(KERN_INFO "Hello, World!\n");
return 0;
}
static void hello_exit(void) {
printk(KERN_INFO "Goodbye, World!\n");
}
module_init(hello_init);
module_exit(hello_exit);
// 内核模块信息。以下为可选内容,不止这些,仅供参考
MODULE_AUTHOR("Hong");
MODULE_DESCRIPTION("A simple hello world module");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
解释:
1)必须包含的头文件:linux/module.h;
2)规定初始化函数 module_init() 和退出函数 module_exit():
2 内核模块编译
使用 make 进行编译,需要提前编写好 Makefile,指定编译为一个可加载的内核模块:
# hello_kernle.ko Makefile
obj-m := hello_kernel.o
编译指令为:
make -C /usr/src/kernels/4.19.91-26.6.19.kos5.x86_64/ M=/root/makefile_test/ko_module/ modules
通常直接将编译指令编写到 Makefile 中,重写 Makefile:
obj-m := hello_kernel.o
all:
make -C /usr/src/kernels/$(shell uname -r)/ M=$(shell pwd) modules
clean:
rm -f *.o *.ko *.mod* *.order *.symvers
执行 make,将触发 make -C /usr/src/kernels/$(shell uname -r)/ M=$(shell pwd) modules;
执行 make clean,将触发 rm -f *.o *.ko *.mod* *.order *.symvers。
3 加载验证内核模块
使用以下指令,操作内核模块:
# 加载内核模块
insmod hello_kernel.ko
# 列出并检索内核模块
lsmod | grep hello_kernel
# 查看内核模块信息
modinfo hello_kernel.ko
# 移除内核模块
rmmod hello_kernel
验证输出:
tail -f /var/log/message

4 常见问题
签名校验失败
[51418.816072] hello_kernel: loading out-of-tree module taints kernel.
[51418.816100] hello_kernel: module verification failed: signature and/or required key missing - tainting kernel

此问题的成因是,选择编译的内核配置项开启了内核模块签名校验功能。
解决方案:
a)手动给编写的内核模块签名(本文不采用);
b)直接关掉内核模块签名校验的配置项。
进入编译内核源码根目录下,进入配置菜单:
注意本示例的内核版本为 4.19
cd /usr/src/kernels/$(uname -r)/
make menuconfig
进入 Enable loadable module support, 关闭 Module signature verification 选项,右下角保存退出。


可 view .config 查看配置是否生效。
重新编译内核模块,问题解决。
内核模块(.ko) 开发入门的更多相关文章
- openresty 前端开发入门五之Mysql篇
openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...
- java WEB开发入门
WEB开发入门 1 进入web JAVASE:标准- standard JAVA桌面程序 GUI SOCKET JAVAEE:企业-浏览器控制 web 2 软件结构 C/S :client ...
- [译]:Xamarin.Android开发入门——Hello,Android Multiscreen深入理解
原文链接:Hello, Android Multiscreen_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android Multiscreen深入理解. 本 ...
- [译]:Xamarin.Android开发入门——Hello,Android深入理解
返回索引目录 原文链接:Hello, Android_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android深入理解 本部分介绍利用Xamarin开发And ...
- [译]:Xamarin.Android开发入门——Hello,Android快速上手
返回索引目录 原文链接:Hello, Android_Quickstart. 译文链接:Xamarin.Android开发入门--Hello,Android快速上手 本部分介绍利用Xamarin开发A ...
- VR原理讲解及开发入门
本文是作者obuil根据多年心得专门为想要入门的VR开发者所写,由52VR网站提供支持. 1. VR沉浸感和交互作用产生的原理: 在之前,我们观看一个虚拟的创造内容是通过平面显示器的,52VR ...
- Eclipse_luna_J2EE_For_JS+tomcat8.0环境搭建、配置、开发入门
一.所有需要的软件.插件等下载地址 J2SE的官方下载路径:http://www.oracle.com/technetwork/java/javase/downloads/index.html Ecl ...
- OWIN的理解和实践(三) –Middleware开发入门
上篇我们谈了Host和Server的建立,但Host和Server无法产出任何有实际意义的内容,真正的内容来自于加载于Server的Middleware,本篇我们就着重介绍下Middleware的开发 ...
- [Cordova] Plugin开发入门
[Cordova] Plugin开发入门 Overview Cordova的设计概念,是在APP上透过Web控件来呈现Web页面,让Web开发人员可以操作熟悉的语言.工具来开发APP.使用Web页面来 ...
- 报表引擎API开发入门— EJB程序数据源
我们前面讲了几个数据源,今天我们来讲一下EJB数据源,这篇讲完我们数据源这部分就讲完了.数据连接不需要直接访问数据库,而是使用EJB做为数据源.FR通过定义程序数据集使用EJB的相关类获取到EJB数据 ...
随机推荐
- Particles
Smiling & Weeping ----我本想边走边爱,可你一个人就挡住了人山人海 牢骚:其实想明白了也就这么一回事,当时一直想dp,(# ̄- ̄#) 正解:其实题目说的明明白白,任选一个数 ...
- Springboot中使用线程池的三种方式
前言 多线程是每个程序员的噩梦,用得好可以提升效率很爽,用得不好就是埋汰的火葬场. 这里不深入介绍,主要是讲解一些标准用法,熟读唐诗三百首,不会作诗也会吟. 这里就介绍一下springboot中的多线 ...
- TDengine 用户案例合集 | 智能环保项目的时序数据处理难点与优化实践
智能环保系统通常涉及大量的传感器和监测设备,以收集环境数据并对其进行分析和处理,这些数据通常是时序数据,即在一段时间内按时间顺序生成的数据,规模庞大且要求快速准确地进行分析和处理.也因此时序数据处理是 ...
- Vue 搭配 Spring MVC 创建一个 web 项目
Vue 搭配 Spring MVC 创建一个 web 项目 想要写一个登录的web应用程序.页面使用Vue,后端使用Spring MVC,最终打成war包,放在tomcat下启动. 1.创建Sprin ...
- Dubbo源码浅析(一)—RPC框架与Dubbo
一.什么是RPC 1.1 RPC概念 RPC,Remote Procedure Call 即远程过程调用,与之相对的是本地服务调用,即LPC(Local Procedure Call).本地服务调用比 ...
- MySQL PXC 集群运维指南
目录 一.PXC方案概述 二.PXC基础知识 三.PXC节点的配置安装 四.PXC节点的上线与下线 五.其他 一.PXC方案概述 Percona XtraDB Cluster (PXC) 是一个完全开 ...
- 2023-10-14:用go语言,给定 pushed 和 popped 两个序列,每个序列中的 值都不重复, 只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时, 返回
2023-10-14:用go语言,给定 pushed 和 popped 两个序列,每个序列中的 值都不重复, 只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时, 返回 ...
- 我试图扯掉这条 SQL 的底裤。
你好呀,我是歪歪. 这次带大家盘一个我觉得有点意思的东西,也是之前写<一个烂分页,踩了三个坑!>这篇文章时,遇到的一个神奇的现象,但是当时忙着做文章搞定这个主线任务,就没有去深究这个支线任 ...
- 使用卷积神经网络训练手写数字识别模型(CNN)
https://www.cnblogs.com/zylyehuo/ 效果展示 目录结构 README.md # Basic MNIST Example pip install -r requireme ...
- JS中的caller属性
JS中的caller属性: 这个属性会返回一个调用该函数对象的外层函数引用.也就是说,如果我们是在函数B()中调用函数A()的,那么只要在A()中调用A.caller,结果就会返回B()functio ...