Linux内核模块

Linux内核模块开发 1.LINUX内核模块基础 1.1 什么是内核模块? Linux内核的整体结构非常庞大,其包含的组件也非常多,如何使用这些组件呢?方法1:把所有的组件都编译进内核文件,即:zImage或bzImage,但这样会导致一个问题:占用内存过多。有没有一种机制能让内核文件本身并不包含某组件,而是在该组件需要被使用的时候,动态地添加到正在运行的内核中呢? 内核模块具有如下特点: 1)模块本身并不被编... 阅读详情

一、 Linux内核模块概念

内核模块是Linux内核向外部提供的一个接口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithic kernel)。单内核的最大优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。
模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其它内核上层的功能。

总之,模块是一个为内核(从某种意义上来说,内核也是一个模块)或其他内核模块提供使用功能的代码块。



二、 Linux内核模块的优缺点

内核模块的动态装载性具有如下优点:
  • 将内核映象的尺寸保持在最小,并具有最大的灵活性;
  • 便于检验新的内核代码,而不需重新编译内核并重新引导。

但是,内核模块的引入也带来了如下问题:
  • 对系统性能和内存利用有负面影响;
  • 装入的内核模块和其他内核部分一样,具有相同的访问权限,因此,差的内核模块会导致系统崩溃;
  • 为了使内核模块访问所有内核资源,内核必须维护符号表,并在装入和卸载模块时修改这些符号表;
  • 有些模块要求利用其他模块的功能,因此,内核要维护模块之间的依赖性。
  • 内核必须能够在卸载模块时通知模块,并且要释放分配给模块的内存和中断等资源;
  • 内核版本和模块版本的不兼容,也可能导致系统崩溃,因此,严格的版本检查是必需的。


尽管内核模块的引入同时也带来不少问题,但是模块机制确实是扩充内核功能一种行之有效的方法,也是在内核
级进行编程的有效途径


三、 Linux内核模块的基本框架

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

static int __init Init(void)
{
//代码块
return 0;
}


static void __exit Exit(void)
{
//代码块
}


module_init(Init);
module_exit(Exit);
MODULE_LICENSE("GPL");


说明:
1. #include <linux/init.h>包含module_init(x)、module_exit(x)等宏定义
2. #include <linux/kernel.h>包含printk等内核封装函数

这些头文件是一个模块最基本的头文件,当我们写一个模块的时候需要加这几个头文件,这几个头文件中有我们模块中最基本的一些符号的定义,即结构体、宏等的定义。


3. module_init(x)修饰Init(),告诉内核加载函数
4. module_exit(x)修饰Exit(),告诉内核卸载函数
5. MODULE_LICENSE("GPL")为遵循GPL规范,内核对驱动的管理十分严格,对应不遵循GPL规范的驱动,内核不愿意非GPL的模块加入内核。一个非GPL模块加入内核的时候,内核会认为内核被污染了而报错。
另外,Linux内核识别的许可证有“GPL”——任意版本的GNU通用公共许可证、“GPL v2”——GPL第二版、
“GPL and additional rignts”——GPL及附加权利、“DualBSD/GPL”——BSD/GPL双许可证和“Proprietary”
——专有等。

6. 内核模块编程特点
<1>不能使用C库和C标准头文件
<2>必须使用GNU规范
<3>没有内存保护机制
<4>不能处理浮点运算
<5>注意同步和并发的问题
<6>注意可移植性



四、 内核模块实例(基于:linux-2.6.35.7, s5pv210)

1. Linux内核模块下一个简单的驱动程序编写:module_demo.c

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

	//加载函数
	static int __init Demo_Init(void)
	{
		printk("Demo init\n");
		return 0;
	}

	//卸载函数
	static void __exit Demo_Exit(void)
	{
		printk("Demo exit\n");
	}

	module_init(Demo_Init);		//程序入口
	module_exit(Demo_Exit);		//程序出口
	MODULE_LICENSE("GPL");		//遵循GPL规范


2. Linux内核模块下驱动程序编译
对驱动程序的编译需具备如下要求:
1. 操作系统版本:内核源码的版本要和驱动安装的目标内核版本一致。
2. 处理器的版本:内核源码要针对具体的硬件平台配置过(如arm、x86平台的不同版本)
3. 工具链:内核源码要编译过。



编写Makefile编译:

KERNEL_DIR=/home/gec/linux-2.6.35.7-gec-v3.0-gt110		//内核源码所在目录
	PWD=$(shell pwd)

	obj-m += module_demo.o 	

	modules:
		$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
	clean:
		$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules clean


3. Linux内核模块下驱动程序调试
几个常用命令:
lsmod:查看当前已加载的模块
insmod:加载模块,内核会执行模块加载函数
rmmod:卸载模块,内核会执行模块卸载函数
modinfo:查看模块信息,需要模块信息文件(modules.dep)的支持
modprobe:加载模块,内核会执行模块加载函数

insmod与modprobe的区别:
1. modprobe需要模块信息文件(modules.dep)的支持
2. modprobe会检查模块的依赖,自动加载依赖的模块

模块的依赖:一个模块使用了另一个模块的变量或函数,这个模块就依赖于另一个模块。其次,如果一个模块中的变量或者函数
希望被被的模块使用,需要将对应的变量或者函数导出。导出方法:
1. EXPORT_SYMBOL:导出的内容所有模块都能使用
2. EXPORT_SYMBOL_GPL:导出的内容只有遵循GPL协议的模块才能使用



五、 Linux驱动程序设计与应用程序设计的区别

1. 应用程序有入口(main函数),但是没有出口。驱动程序有入口也有出口。
2. 应用程序编程的时候可以使用标准的C库,即可以使用libc提供的函数。驱动程序不能使用标准的C库,只能使用内核提供的函数。
3. 驱动程序稳定的、精简、可移植性
4. 应用程序和驱动程序的编译过程不同,驱动程序编译的时候,需要内核源码。




Linux内核模块编程 Linux内核模块编程 (作者:Baron_wu 禁止转载) 首先,创建一个内核模块并插入Linux内核中。这是实验第一部分 首先查看当前内核模块使用情概况:lsmod Module:模块名 Size:模块大小 Used by:这些模块在哪被使用 接下来编写一个simple.c的程序,当加载和卸载内核模块时给出适当的消息。 代码如下: #include &lt;linux/init.h&gt... 阅读详情

相关推荐

Linux 驱动开发之内核模块开发 (一)—— 内核模块机制基础

一、内核模块的概念 1、什么是模块?        内核模块是一些可以让操作系统内核在需要时载入和执行的代码,同时在不需要的时候可以卸载。这是一个好的功能,扩展了操作系统的内核功能,却不需要重新启动系统,是一种动态加载的技术。 特点:动态加载,随时载入,随时卸载,扩展功能 2、内核模块的加载作用       内核模块只是向linux内核预先注册自己,以便于将来的请求使用;由目标代

知秋一叶 5772

一文讲解内核模块依赖!

模块加载时,加载程序将去处理未决符号,在特殊段中搜索符号的名字,如果找到,则将获得的地址填充在被加载模块的相应段中,这样符号的地址就可以确定。解决这个问题的方法是将两个模块放在一起编译,或者将dep模块放在内核源码中,先在内核源码下编译完所有的模块,再编译vser模块。这在一个驱动调用另一个驱动代码时比较常见,这样模块和模块之间就形成了依赖关系,使用导出符号的模块将会依赖于导出符号的模块。内核将会创建模块依赖关系的链接,只有当依赖于这个模块的链表为空时,模块才能被卸载.举个具体的例子,下面是两个C文件,

youzhangjing_的博客 2305

手把手教你在全新服务器内网安装OpenEuler 22.03 LTS SP4+ 安装 openGuass 5.0.0(LTS) 数据库

openEuler是面向数字基础设施的操作系统,支持服务器、云计算、边缘计算、嵌入式等应用场景,支持多样性计算,致力于提供安全、稳定、易用的开源服务器Linux操作系统。

cgqyw的专栏 3738

linux内核中模块间相互依赖的自动连接程序:modprobe外部程序和request_module()函数的分析

以下内容总结自《understanding the linux kernel》 在Linux系统中一个包括但不限于驱动模块,可能需要一个或者多个其他的模块,这些模块又可能需要其他的模块。为了内核能够自动链接模块,内核需要创建一个内核线程来执行modprobe程序,该线程要考虑由于模块依赖所引起的所有可能因素。 modprobe外部程序和insmod类似,链接在命令行中指定的一个模块。然而,mo...

仗劍走天涯 1642

Agisoft Metashape相机标定笔记

使用Metashape进行自动相机标定是可能的。(可选:使用打印的棋盘格图案,但需保证它是平坦的且单元格是正方形)。相机标定步骤支持全相机标定矩阵的估计,包含非线性的畸变参数。相机模型的细节请参照附录D——相机模型板块。:在通用的工作流程中,相机标定步骤可以跳过。因为Metashape会在图像定向过程中进行相机自标定。但是,如果定向结果不稳定,例如,由于影像之间缺乏连接点,额外进行单独的相机标定步骤也许是有用的。

天桥飞熊的博客 3976

嵌入式设备系统日志记录及调试技巧_嵌入式日志系统(1),如何成为杰出的程序员

这里面我使用的芯片为哈弗体系,全局常量存储编译器默认分配在flash,需要注意如果使用片内flash时,注意存储调试等级的flash块不要与代码区重合,要不然修改调试等级擦除flash块同时PC指针指向当前块的代码区,会导致仪器死机;这个也是之前用的比较多的,以上代码是模仿linux 内核的写法,可以比较好的做到日志信息分层,编译时相加对应的编译开关即可。但有个弊端就是,切换debug等级时,需要重新编译且需更新固件,而嵌入式设备出现异常后更新固件往往复位后,故障有时很难复现,调试起来比较浪费时间。

2401_84240431的博客 1294

Linux Kernel Module知识大全之一(基础)

把Linux Kernel的一些功能移动到内核外边, 需要时安装,不需要时卸载。这样即可以Kernel 更加轻便小巧,使用某个板块的时候,只需要将其当做想U盘一样的插件一样。让Kernel如在imx6上连接模拟摄像头,先运行模拟摄像头对应的驱动模块 camera.ko文件,然后对应的工程执行文件运行就行。既然知道了Kernel Module的作用之后,那么就可以先从基本的入手:怎么从一个已有的Kernel Module 进行。

斯是陋室,惟汝德馨 1262

工业相机,大恒,面振相机8脚电源线和I/O触发接口线,颜色和接法说明和触发软件设定

上图: 说明一下,工业相机有TTL逻辑电平触发,也有光耦触发等。 这里一般我们用电路板驱动,就用GPIO触发模式, 这里,准备了两个GPIO触发模式,为LINE2,LINE3都可以选择,然后有一个GPIO_GND 如果,你只有一个触发接口,那么如图,选两个就好了。 实际接法如图。 ...

山云的专栏 1万+

Linux内核模块的编译基础知识

关于内核驱动的东西网络上有很多,但网上的东西还是感觉有点笼统,读过之后就忘了,还是需要写下来,或者写到本子上,自己形成一个概念好一些。读了这本书上的东西,把觉得好的东西写下来,已备不时之用,也强化记忆。1 内核模块的概念介绍内核模块的同时,也说明一下和应用程序的区别。虽然内容很多,但觉得都很有用。1、内核模块是一些可以让操作系统内核在需要时载入和执行的代码,同时在不需要的时候可以卸载。这是一个好的功能,扩展了操作系统的内核功能,却不需要重新启动系统,是一种动态加载的技术。特点:动态加载,随时载入,随时卸载,

草莽农夫 2180

Yield Management软件:Lam Research二次开发_(5).缺陷分析与分类方法

在半导体制造过程中,缺陷分析和分类是提高良率管理(Yield Management)的关键步骤。通过准确地识别和分类缺陷,可以更好地理解工艺过程中的问题,从而采取有效的措施来提高生产效率和产品质量。本节将详细介绍缺陷分析和分类的方法,包括缺陷检测、特征提取、分类算法及其在Lam Research软件中的应用。

2401_87715305的博客 690

【BlueZ】编译产物详解:可执行文件/库文件/工具的生成路径与用途

BlueZ二次开发编译产物机制解析 摘要:在BlueZ蓝牙协议栈二次开发中,90%的报错源于对编译产物类型和路径的混淆。本文系统剖析BlueZ的三阶段编译机制:1)配置阶段生成Makefile;2)编译阶段在.libs目录下产生临时库和可执行文件(不可直接运行);3)安装阶段将产物部署到系统标准路径。重点解析守护进程、命令行工具、动态库的核心路径差异,并针对五大高频问题(如临时库运行崩溃、动态库不匹配、系统覆盖等)给出解决方案。

byte轻骑兵的技术小窝 1万+

操作系统复习

第一章 绪论 操作系统的定义 一般来说,操作系统是管理计算机系统中的软件与硬件资源,控制程序执行,改善人机界面,合理组织计算机工作流程和为用户使用计算机提供良好运行环境的一种系统软件。 先跳过 第二章 操作系统的结构 接口 现代操作系统至少会提供两种类型的接口供用户使用:命令接口与系统调用 命令接口 命令接口通常呈现给用户两种形态:命令行界面与图形用户界面 系统调用 系统调用把应用程序的请求传给内核,调用相应的内核函数完成所需的处理,将处理结果返回给应用程序。 处理器设有两种模式: “用户模式”:应用程

Gxyhqzt的博客 2478

Unity Hololens2开发|(一)环境配置

开发过程中预览和调试应用:可以在电脑上的 Unity 编辑器中以播放模式本地运行应用,并将体验流式传输到 HoloLens2。将来自 HoloLens2 的输入(视线、手势、语音和空间映射)发送到电脑,在其中内容以虚拟沉浸式视图渲染。在HoloLens2设备中,打开Settings面板,依次选择Update & Security > For Developers,打开“Developer Mode”。在开发计算机中打开控制面板,依次选择“更新和安全> 开发者选项”,打开“开发人员模式”;

游戏开发小Y的博客 14万+

【Linux驱动】 Linux内核模块

在Linux系统中,设备驱动会以内核模块的形式出现,学习Linux内核模块编程是驱动开发的先决条件。第一次接触Linux内核模块,我们将围绕着“Linux内核模块是什么”,“Linux内核模块的工作原理”以及 “我们该怎么使用Linux内核模块”这样的思路一起走进Linux内核世界。内核模块的概念:内核模块是什么东西?为什么引入内核模块这一机制?内核模块的原理:内核模块在内核中的加载、卸载过程,深入剖析内核模块如何导出符号。

C/C++软件工程师、嵌入式软件工程师、物联网研发工程师、C/C++讲师、物联网讲师、嵌入式讲师、鸿蒙讲师---欢迎大家一起交流(私信添加博主微信) 3135

【python爬虫--爬取电商商品及对其销量、好差评等数据进行分析】Python爬虫爬取电商商品及大数据分析-实战

选择目标电商网站:这里选择爬取两个不同电商网站(比如京东、淘宝)上的商品数据,包括商品名称、价格、销量和评价信息。编写爬虫:通过爬虫获取商品信息并保存数据。数据清洗与对齐:将两个电商网站抓取到的数据进行统一清洗和对齐。数据分析:进行销量分析、好评与差评分析等。

Dreams°的博客 4013

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【Linux内核模块】Linux内核模块简介

在Linux操作系统中,内核模块(Loadable Kernel Module, LKM)是实现系统功能扩展的核心机制。2025年Linux 6.8版本引入的动态内核组件加载机制(DKLM)和AI增强模块,标志着内核模块技术进入全新发展阶段。本文将系统解析Linux内核模块的技术原理、开发实践,结合2025年最新特性,为开发者提供从入门到进阶的完整指南。

byte轻骑兵的技术小窝 1847

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【Linux内核模块】Linux内核模块程序结构

如果你已经写过第一个 "Hello World" 内核模块,可能会好奇:为什么那个几行代码的程序能被内核识别?那些module_init、MODULE_LICENSE到底是什么意思?今天咱们就来扒一扒内核模块的程序结构,搞清楚一个合格的内核模块到底由哪些部分组成,每个部分又承担着什么角色。​

byte轻骑兵的技术小窝 2063

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Linux内核模块详解

内核模块 实验目的 内核模块是Linux操作系统中一个比较独特的机制。通过这一章学习,希望能够理解Linux提出内核模块这个机制的意义;理解并掌握Linux实现内核模块机制的基本技术路线;运用Linux提供的工具和命令,掌握操作内核模块的方法。 实验内容 针对三个层次的要求,本章安排了3个实验。 第一个实验,编写一个很简单的内核模块。虽然简单,但它已经具备了内核模块的基本要素。与此同时,...

Kunaly 2万+

linux 内核模块

另外,内存管理会提供虚拟内存的机制,该机制可以让进程使用多于系统可用Memory的内存,不用的内存会通过文件系统保存在外部非易失存储器中,需要使用的时候,再取回到内存中。Linux的文件系统模块采用先进的虚拟文件系统技术,屏蔽了各种文件系统的差别,为处理各种不同的文件系统提供了统一的接口,支持多种不同的物理文件系统达90多种。Linux 内核采用的是模块化技术,这样的设计使得系统内核可以保持最小化,同时确保了内核的可扩展性与可维护性,模块化设计允许我们在需要时才将模块加载至内核,实现动态内核的调整。

u010230019的博客 1679

Linux驱动开发——内核模块

目录 内核模块的由来 第一个内核模块程序 内核模块工具 将多个源文件编译生成一个内核模块 内核模块参数 内核模块依赖 关于内核模块的进一步讨论 习题 内核模块的由来 最近一直在玩那些其它的技术,眼看快暑假了,我决定夯实一下我的驱动方面的技能,迎接我的实习,找了一本书,接下来就跟着这本书学了 先来看第二章,内核模块 Linux是宏内核(或单内核)的操作系统的典型代表,它和微内核(典型的代表是 Windows操作系统)的最大区别在于所有的内核功能都被整体

qq_52479948的博客 2699

Linux内核模块简介

当我们谈论Linux内核时,不可避免地要提到内核模块。内核模块是一种动态加载到内核中的软件,它可以在运行时添加到内核中,从而扩展内核的功能。在这篇博客中,我们将深入探讨Linux内核模块的基本概念和作用,并通过一个简单的示例来展示如何创建和使用内核模块。

qq_36733726的博客 2657

Linux动态加载内核模块

Linux属于单内核,为了弥补单内核扩展性与维护性差的缺点,Linux引入动态可加载内核模块,模块可以在系统运行期间加载到内核或从内核卸载。模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。下面是一个简单的例子: (1)模块hello.c文件#i

傻红就是不爱跑步的博客 2万+

小白学Linux之内核模块编程

Linux内核模块编程Linux内核模块编程是一个很重要的知识点。尤其是编写底层驱动程序时,一定会涉及到它。内核模块编程也是Tiger哥学习Linux时第一节课所接触的知识。由此可以看出它的important,也可以看出其实它很easy。一前言:1.什么是内核模块1>内核模块是具有独立功能的程序。它可以被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间中运行。 2> 模块编程和内核版本密切相连,因为不同的内核版本中某些函数的函数名会有变化。因此模块编程也可以说是内核编程。3>特

冀博 2万+
上一篇: C语言产生随机数
下一篇: Linux驱动简介
SLASH_24
博客等级 码龄10年 7粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值