Linux 模块

news/2025/2/24 15:45:21/文章来源:https://www.cnblogs.com/tggpx/p/18730492

什么是 Linux 模块

Linux模块,也就是可加载内核模块(LKMs),允许在运行时动态加载到内核中。
这说明两点:

  • 是内核模块, 也就是说是内核的一部分, 只能依赖内核的接口, 且必须遵循内核的规则.
  • 运行时可加载, 这避免了重复编译内核和重启系统. 并且内核和模块是分开的, 部署更灵活. 同时也可以只在需要的时候加载模块, 节省内核的内存占用.

开发模块时常用的命令

insmod module.ko # 加载模块
rmmod module.ko # 卸载模块
modprobe module.ko # 智能加载模块, 会自动解决依赖
lsmod # 查看已加载的模块
modinfo module.ko # 查看模块信息
depmod -a # 更新模块依赖
dmesg # 查看内核日志
uname -r # 查看内核版本

如何实现一个 Linux 模块

  1. 编写模块代码

    #include<linux/module.h>
    #include<linux/init.h>
    // 不能依赖c库, 只能使用内核提供的接口MODULE_LICENSE("Dual BSD/GPL"); // 必须有,否则报错. 模块许可证,许可可选static int __init myinit(void) // 必须有,在模块加载时调用
    {printk("Hi module!\n");return 0;
    }static void __exit myexit(void) // 必须有,在模块卸载时调用
    {printk("Bye module!\n");
    }module_init(myinit); // 必须有,指定 这是模块加载时调用的函数
    module_exit(myexit); // 必须有,指定 模块卸载时调用的函数
    
  2. 编写 Makefile

    obj-m := module.o // 表明有一个模块要从module.o建立
    module-objs := file1.o file2.o // 表明module.o的依赖, file1.o会自动根据名字找到对应的源文件file1.c(其他后缀的情况我不清楚)生成. 如果一个模块只由一个源文件生成, 可以直接写成obj-m := file1.o#generate the path
    CURRENT_PATH:=$(shell pwd)#the current kernel version number
    LINUX_KERNEL:=$(shell uname -r)
    #the absolute path
    LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)#complie object
    all:make -C $(LINUXKERNELPATH) M=$(CURRENT_PATH) modules# -C 改变目录到指定内核目录, M= 指定模块所在目录#clean
    clean:make -C $(LINUXKERNELPATH) M=$(CURRENT_PATH) clean
    

    编译模块有几个前提:

    • 编译模块实际使用的是内核的Makefile, 所以必须要先下载对应的内核代码.
    • 保证你有版本足够新的编译器, 模块工具, 以及其他必要工具. 在内核Documentation/Changes 列出了需要的工具版本
  3. 加载/卸载模块
    insmod module.ko
    rmmod module.ko
    modprobe module.ko # 与insmod的区别是如果要加载的模块引用了内核中为定义的符号,modprobe会在当前模块搜索路径中寻找其他模块

Linux 模块是如何工作的

.ko文件是什么

本质是一个ELF文件, 和.o文件差不多,都是REL(relocatable file), 只是多了一些元数据,比如模块许可证, 然后把多个.o打包成一个.ko, 还多了导出的符号表.

模块加载的过程

模块加载时会使用一个系统调用sys_init_module, 在内核代码中使用SYSCALL_DEFINE3(init_module,...)来定义这个系统调用.
主要代码是

err = copy_module_from_user(umod, len, &info);
...
return load_module(&info, uargs, 0);

copy_module_from_user是把用户空间的模块数据拷贝到内核空间, 这部分内容需要理解内存管理机制.最终会把模块数据放到info中.

load_module涉及到几个部分, ELF解析,内存管理等, 暂时不深入.

怎么把用户空间数据copy到内核空间

补充: 内核模块和用户程序的区别

  • 只连接到内核, 能够调用的唯一的函数是内核输出的那些.
  • 错误处理
  • 用户空间和内核空间的不同
  • 内核的并发, 所以内核代码必须是可重入的--能在多个上下文中同时运行
  • 应用程序存在于虚拟内存中, 有一个非常大的堆栈区. 内核, 相反, 有一
    个非常小的堆栈,并和所有内核空间调用链共享;
  • 小心使用__开始的函数, 如果你调用这个函数, 确信你知道你在做什么.
  • 内核代码不能做浮点运算, 使能浮点将要求内核在每次进出内核空间的时候保存
    和恢复浮点处理器的状态, 增加了不必要的开销.
  • linux 内核头文件提供了方便来管理你的符号的可见性, 如果需要输出符号给其他模块使用需要使用EXPORT_SYMBOL()/EXPORT_SYMBOL_GPL()宏._GPL表示只给GPL许可证的模块使用.

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

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

相关文章

npccctf第一周wp

1、全网呼叫密码人 题目 from Crypto.Cipher import AES from Crypto.Util.number import * from Crypto.Util.Padding import pad """ Dinzheng先生准备去买一根RuiKeV电子烟,在付款的时候忘记了它的支付密码。 还好他的朋友早有准备,留下了若干个密保问题,…

如何利用CRM系统进行客户细分和精准营销?

——怎么做才能在CRM系统里对客户进行细分并精准营销呢? 我有一个朋友这么问我。 其实,想做到这个并不难,不过需要先明白这两个的核心概念是什么。简单来说,客户细分——根据客户的不同特点,把客户分成几个群体。 精准营销——根据这些细分好的群体,量身定制符合他们需求…

文科生的我用DeepSeek+AI程序员半小时开发了一个小程序

作者:AI工具集 有时候我突发奇想要做个小工具,但是碍于不会编程,没办法进行下去。 但是学习编程要花很长时间,而且以我的水平,还不一定学得懂。我就在想,能不能通过AI生成一个网页、小程序或者App呢?经过实战手搓,发现真的可以!DeepSeek满血版“AI程序员” 正好我看见…

优化性能钩子useMemo

执行顺序 useMemo 是同步执行,而 useEffect 是异步的。 import { useMemo, useState, useEffect } from react;function TestComponent() {const [count, setCount] = useState(0);console.log(普通代码:在渲染期间同步执行);useMemo(() => {console.log(useMemo:在渲染期…

BUUCTF-Web方向21-25wp

[HCTF 2018]admin 打开环境,有三处提示,一个跳转链接,一个登录注册,一个提示不是admin点击hctf,无法访问注册个账号,依旧无法查看,看来需要admin账号弱口令 爆破密码当密码未123长度明显不同登录session伪造 在修改密码界面,提示session下载该源码查看,index.php {% i…

useMemo 与 useEffect

执行顺序 useMemo 是同步执行,而 useEffect 是异步的。 import { useMemo, useState, useEffect } from react;function TestComponent() {const [count, setCount] = useState(0);console.log(普通代码:在渲染期间同步执行);useMemo(() => {console.log(useMemo:在渲染期…

测试用例管理工具2

一、bug的等级 (1)1级bug (致命bug) (2)2级bug(严重bug) (3)3级bug(一般bug) (4)4级bug(简易性bug)- 划分- 1级bug (致命bug):必须优先修改,在测试中较少出现,一旦出现应立即中止当前版本测试; 致命bug: (1)常规操作引起的崩溃,死机,死循环,内存泄…

FPGA Assembly

FASM 是一种文件格式,用于指定 FPGA 比特流中需要置1或清0的位。FASM 的设计初衷是提供一个中间层,令 FPGA 布局布线工具无需关心实际运行的 FPGA 比特流文件格式而工作。FASM 文件格式具有以下特性:从文件中删除任意一行都不会影响其有效性(注:这里的“有效性”指的是能正…

Flink 实战之维表关联

生产应用中,经常遇到将实时 **流式数据** 与 **维表数据** 进行关联的场景。常见的维表关联方式有多种,本文对以下 3 种进行了实现,并对每种方法的优缺点进行了比较:1. 预加载维表 2. 异步 IO 3. 广播维表下面分别使用不同方式来完成维表 join 的实验,附源码和实时动效。F…

Sa2VA环境搭建推理测试

引子 Sa2VA模型通过结合SAM-2和LLaVA,将文本、图像和视频统一到共享的LLM标记空间中,能够在少量指令微调下执行多种任务,如图像/视频对话、指称分割和字幕生成。该模型在视频编辑和内容创作中展现出强大的性能,在相关基准任务中达到了SOTA水平。OK,那就让我们开始吧。一、…

20-bluecms代码审计、thinkphp相关知识cve和cnvd编号申请

1、对bluecms进行代码审计,分析复现文件上传、ssti模板注入、文件删除等漏洞 文件上传审计admin/tpl_manage.php 文件发现,在do_edit模块有三个参数(act = do_edit、tpl_name = 写入文件名称、tpl_content = 写入内容,且代码中未对文件名过滤,导致可以上传任意文件。查看对…

ios SDK AB 开关切换

在数据库的这个服务器 然后再ctest1数据库新建编辑器然后查询select* fromapp_config ac whereaccess_no = 12100186 //这个是应用IDand module = abSwitchand param_name = export_otel_ab查到后,把param_value改为B,或者A,然后回车,然后点击图中的保存 保存后等两分钟,…