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

LDD学习笔记 -- Linux内核模块

LDD学习笔记 -- 内核模块

    • 简介
    • LKM类型
    • Static Linux Kernel Module
    • Dynamic Linux Kernel Module
    • LKM编写语法 @syntax@
    • 详细描述
      • 内核头文件
      • 用户空间头文件
      • Module Initialization Function
      • Module Cleanup Function
      • Keyword & Tag
      • 宏 __init __exit
      • LKM入口注册
      • Module Metadate(Module Description)
    • 构建内核模块 Building
      • In tree module
      • Out of tree module
      • Kernel Build System
      • 在host系统上构建并安装内核模块
      • 为Target系统构建并安装内核模块

简介

在运行时添加 / 删除的代码

Linux支持在系统启动和运行时从内核中动态的插入或移除代码。在运行时添加/删除的代码叫做内核模块。

Linux内核模块通过向内核引入新的功能(安全、设备驱动、文件系统驱动、系统调用、其他)来动态的扩展内核的功能。模块化的方法,像正在运行的内核的插件。

嵌入式Linux系统可以由 最小的基本内核镜像 + 可选的设备驱动/其他功能通过模块插入按需提供

例如一个热拔插的USB设备,它的驱动程序(Linux内核模块),当其插入后会动态加载到内核中

LKM类型

  • Static Linux Kernel Module
  • Dynamic Linux Kernel Module

Static Linux Kernel Module

当构建Linux内核时,将模块静态的链接到内核镜像。模块成为最终内核镜像的一部分,内核镜像size变大。
不能卸载,运行中模块永久的占据内存。

Dynamic Linux Kernel Module

不会在编译期间嵌入内核镜像,单独编译和链接生成.ko文件
可以使用用户空间程序insmod, modprobe, rmmod从内核中加载/卸载,从而允许更加灵活的管理内核模块。

LKM编写语法 @syntax@

  • Header section
  • Code
  • Registration
  • Module description
#include <linux/module.h>/* This is module initialization entry point */
static int __init my_kernel_module_init(void)
{pr_info("hello kernel~\n");return 0;
}/* This is module clean-up entry point */
static void __exit my_kernel_module_exit(void)
{pr_info("my hello module exit\n");
}/* registration */
module_init(my_kernel_module_init);
module_exit(my_kernel_module_exit);/* This is description information about the module */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NAME");
MODULE_DESCRIPTION("A kernel module to print hello");

详细描述

运行在内核空间的。

内核头文件

内核源码树目录下 /include/linux 有所有的内核头文件,例如module.h
内核模块代码是运行在内核空间的,需要使用内核头文件,在内核构建过程中,没有用户空间库链接到
内核模块。不能将内核模块与C标准库链接。因此在写内核模块的时候不能使用任何用户空间的头文件。

用户空间头文件

例如C标准库里的stdio.h

Module Initialization Function

like main,做与初始化相关的事情
初始化模块,在模块插入 / 静态链接模块的系统引导期间调用。
返回 0 表示成功;返回 非0 表示失败从而阻止模块加载。
内容:设备的一些初始化,初始化设备私有数据结构,动态地为各种内核数据结构和服务请求一些内存,请求分配 major number, minor number, 创建设备文件, 在函数中执行各种操作。 (后面的字符设备驱动里)

Module Cleanup Function

复杂清理模块任务,在模块被移除时候调用。

Keyword & Tag

  • static就是常用的意思,修饰的函数只在这个文件中有效
  • __init 标记表示此代码是模块初始化特有的,模块初始化完成后可以从内存中丢弃,以节省内核内存。对于减少动态加载模块中的内核内存很有用。

宏 __init __exit

__init__exit是Linux kernel中使用的C语言宏。
定义在LINUX_SRC/include/linux/init.h
是编译器指令或属性

#define __init			__section(.init.text)
#define __initdata		__section(.init.data)
#define __initconst 	__section(.init.rodata)#define __exit			__section(.exit.text)

编译器指令,指示编译器将数据或代码保存在称为"init."的输出段中(在最终的内核印象中)。
只对静态模块有意义!

__init目的释放内核运行时内存。初始化函数执行后,在引导期间,内核将从内存中释放.init部分,只对静态模块有用,函数只会在boot引导的时候调用一次,无法卸载的内置驱动程序不需要再内存中保存其对init函数的引用。
因为有10万个内置模块~

通过使用__init技术,将函数推入init段,这是一个特殊的段,内核后面可以释放它

__exit目的:内建模块,不需要清理函数,当其与清理函数一起使用时,内核构建系统将在构建过程中排除这些函数,作为构建系统的标记,将清理函数从最终内核印象中排除。不编译了呗~,

LKM入口注册

module_init module_exir Macros,定义在linux/module.h
在内核编程中,需要向内核注册初始化和清理函数。
使用内核提供的宏 module_initmodule_exit来完成
分别将参数添加到内核init入口点数据库(the init entry point database of the kernel)和内核出口点数据库(the exit entry point database of the hernel)

Module Metadate(Module Description)

MODULE_LICENSE 该内核模块的开源许可类型
MODULE_AUTHOR
MODULE_DESCRIPTION

可以使用objdump modinfo 提取内核模块的元数据,即模块信息

构建内核模块 Building

  • 与内核镜像静态链接
  • 作为可动态加载的模块
    • In tree module
    • out of tree module

In tree module

使用make modules 命令去构建Linux内核所有的动态可加载的内核模块,都是In tree module,他们在Linux kernel tree内部。意味着得到内核开发人员和维护者的认可。

Out of tree module

加载它会污染内核,加载该模块到内核中时内核会发出一个警告,内核中也会设置一个taint flag,可忽略。指在内核源码树之外的。

Kernel Build System

调用"kbuild"构建内核,不用关心使用哪种编译器开关或参数。

在编译外部模块前,需要有预构建的完整内核源码,因为它包含配置项和构建时需要的头文件。注:这个linux kernel源码的版本必须和目标板运行的版本一样哦~

  • 下载完整的内核源码,并build它;

make -C <path to linux kernel tree> M=<path to your module> [target]
[Target] :modules modules_install clean help
C是为了使用linux kernel源码的顶层Makefile,指定kbuild的编译开关,依赖列表,版本符号
本地Makefile需要指定kbuild的变量: obj-<X>:=<module_name>.o
X = n ,不编译模块; =y,编译模块连接到kernel image; =m,编译动态内核模块

在host系统上构建并安装内核模块

uname -r 查看机器上的linux版本 5.4.0-150-generic 这里是预编译的内核源码和内核头文件路径/lib/modules/5.4.0-150-generic/
在这里插入图片描述
make -C /lib/modules/5.4.0-150-generic/build/ M=$PWD modules
在这里插入图片描述
sudo insmod hello.ko
sudo rmmod hello.ko
dmesg
在这里插入图片描述

为Target系统构建并安装内核模块

注意已经在~/.bashrc中添加了目标板的编译工具链路径,目标板也预编译了。
make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf- -C ../../Linux-4.9.88/ M=$PWD modules
make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf- -C ../../Linux-4.9.88/ M=$PWD clean

file hello.ko 查看模块的体系结构
modinfo hello.k o 查看模块的信息
在这里插入图片描述
arm-buildroot-linux-gnueabihf-objdump -h hello.ko 分析内核对象文件的各个部分
在这里插入图片描述

在目标板上安装模块
这里使用最方便的方法,使用WindTerm工具SSH方式登陆目标板,把hello.ko文件拖到板子里 。

sudo insmod hello.ko
sudo rmmod hello.ko
dmesg

SSH连接的dmesg
在这里插入图片描述
串口的输出
在这里插入图片描述
在目标系统板上测试内核模块,成功~

相关文章:

LDD学习笔记 -- Linux内核模块

LDD学习笔记 -- 内核模块 简介LKM类型Static Linux Kernel ModuleDynamic Linux Kernel ModuleLKM编写语法 syntax详细描述内核头文件用户空间头文件Module Initialization FunctionModule Cleanup FunctionKeyword & Tag宏 __init __exitLKM入口注册Module Metadate&#…...

springboot整合springbatch批处理

springboot整合springbatch实现批处理 简介项目搭建步骤 简介 项目搭建 参考博客【场景实战】Spring Boot Spring Batch 实现批处理任务&#xff0c;保姆级教程 步骤 1.建表 建表sql CREATE TABLE student (id int NOT NULL AUTO_INCREMENT,name varchar(100) NOT NULL C…...

答案解析——C语言—第2次作业:转义字符

本次作业的链接如下&#xff1a;C语言—第2次作业&#xff1a;转义字符 1.下面哪个不是C语言内置的数据类型&#xff1a; C char //字符数据类型short //短整型int //整形long //长整型long long //更长的整形float //单精度浮点数double //双精度浮点数 …...

HTML5-新增表单input属性

新增表单属性 form控件主要新增的属性: autocomplete 是否启用表单的自动完成功能&#xff0c;取值&#xff1a;on&#xff08;默认&#xff09;、off novalidate 提交表单时不进行校验&#xff0c;默认会进行表单校验 autocomplete属性 概念&#xff1a;autocomplete属性…...

css-、串联选择器和后代选择器的用法

& &表示嵌套的上一级&#xff0c;这是sass的语法&#xff0c;代表上一级选择器 .btn {&.primary {background-color: #007bff;color: #fff;} } 编译出来的结果是同一个元素&#xff0c;有两个类名&#xff0c;两个类名之间没有空格&#xff1a; .btn.primary {…...

nifi详细介绍--一款开箱即用、功能强大可靠,可用于处理和分发数据的大数据组件

目录 目录 一、引言 二、NiFi 的历史背景介绍 三、NiFi 是什么&#xff1f; 核心特性 应用领域 四、NIFI 入门 五 、NiFi 工作流程 六、实际应用场景 七、优势总结 一、引言 NiFi&#xff08;Apache NiFi&#xff09;&#xff0c;全名为“Niagara Files”&#xff0…...

K8S Dashboard登录Token过期问题处理

整体思路 用户访问一个页面&#xff0c;在该页面中设置一个超链接&#xff0c;点击跳转至K8S Dashboard&#xff1b;跳转后&#xff0c;使用剪贴板上已复制的Token粘贴到Dashboard页面中的输入框登录即可。 写个定时任务将Token复制到页面上&#xff0c;过期了重新再登…...

x-cmd pkg | trafilatura - 网络爬虫和搜索引擎优化工具

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 trafilatura 是一个用于从网页上提取文本的命令行工具和 python 包: 提供网络爬虫、下载、抓取以及提取主要文本、元数据和评论等功能可帮助网站导航和从站点地图和提要中提取链接无需数据库&#xff0c;输出即可转换…...

前端知识点(面试可看) —— JS

摘要 马上就要毕业啦&#xff0c;没有参加2023年的秋招&#xff0c;准备在最近开始找全职或者实习工作&#xff0c;然后也马上过年了&#xff0c;总结和理一下自己的知识要点&#xff0c;参加2024年的春招。 1. JS的执行流程 浏览器的V8引擎收到到执行的JS代码V8结构化这段代…...

CSRF总结

CSRF 文章目录 CSRF漏洞原理漏洞危害漏洞防护CSRF攻击流程CSRF和XSS的区别CSRF漏洞挖掘及利用 CSRF 跨站点请求伪造&#xff08;CSRF&#xff09;攻击者会诱导受害者点击事先伪造好的url或者链接&#xff0c;点击后&#xff0c;攻击者就可以盗用你的身份&#xff0c;以你的身份…...

降维算法的简单介绍

降维算法 降维算法&#xff1a; 通过减少数据的维度&#xff0c;如主成分分析和 t-分布邻域嵌入等。 降维通俗的讲&#xff0c;是通过减少数据的维度来处理高维数据的过程。降维算法有助于消除数据中的冗余信息&#xff0c;减少噪声&#xff0c;并提高计算效率。以下是一些常见…...

k8s的声明式资源管理

在k8s当中支持两种声明资源的方式&#xff1a; 1、 yaml格式&#xff1a;主要用于和管理资源对象 2、 json格式&#xff1a;主要用于在API接口之间进行消息传递 声明式管理方法(yaml)文件 1、 适合对资源的修改操作 2、 声明式管理依赖于yaml文件&#xff0c;所有的内容都…...

Git | tag相关命令

语法命令 git tag -h usage: git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]<tagname> [<head>]or: git tag -d <tagname>...or: git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit&g…...

【Java期末】学生成绩管理系统

诚接计算机专业编程任务(C语言、C、Python、Java、HTML、JavaScript、Vue等)10/15R&#xff0c;如有需要请私信我&#xff0c;或者加我的企鹅号&#xff1a;1404293476 本文资源下载地址&#xff1a;https://download.csdn.net/download/weixin_47040861/88697244 —————…...

顶顶通呼叫中心中间件通过队列外呼拨打另一个sip并且放音(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件通过队列外呼拨打另一个sip并且放音 一、添加acl 打开ccadmin->点击配置文件->点击acl.conf->在</list>后面添加一条图中的信息->muqi是我自己设置的名字你们可以修改为自己需要的名字->添加好了点击提交XML->在运维调试点…...

SQL Server从0到1——报错注入

报错注入分为三类&#xff1a;隐式转换&#xff0c;和显示转换&#xff0c;declare函数 隐式转换&#xff1a; 原理&#xff1a;将不同数据类型的数据进行转换或对比 select * from test.dbo.users where (select user)>0 #对比 select * from test.dbo.users where ((sel…...

【python高级用法】线程

前言 Python通过标准库的 threading 模块来管理线程。这个模块提供了很多不错的特性&#xff0c;让线程变得无比简单。实际上&#xff0c;线程模块提供了几种同时运行的机制&#xff0c;实现起来非常简单。 线程模块 线程对象Lock对象RLock对象信号对象条件对象事件对象 简单…...

分布式高级知识点

分布式一致性算法: Paxos Paxos 是一种分布式一致性算法,用于在分布式系统中达成共识。它可以保证,即使在存在节点故障的情况下,系统也能就某个值达成一致。 Paxos 算法的基本思想是,首先选出一个协调者(leader)。协调者负责向其他节点发送提案(proposal)。其他节点收…...

Linux 命令之 dpkg 的简单使用

查询已安装的软件包及其依赖关系 dpkg -s name...

Ubuntu20.04服务器使用教程(安装教程、常用命令、故障排查)持续更新中.....

安装教程&#xff08;系统、NVIDIA驱动、CUDA、CUDNN、Pytorch、Timeshift、ToDesk&#xff09; 制作U盘启动盘&#xff0c;并安装系统 在MSDN i tell you下载Ubuntu20.04 Desktop 版本&#xff0c;并使用Rufus制作UEFI启动盘&#xff0c;参考UEFI安装Ubuntu使用GPTUEFI模式安…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...