0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

内核模块依赖什么意思

麦辣鸡腿堡 来源:嵌入式Linux充电站 作者:Vincent 2023-09-26 16:51 次阅读

通常情况下,一个模块只使用内核导出的符号,自己不导出符号。但是如果一个模块需要提供全局变量或函数给另外的模块使用,那么就需要将这些符号导出。

这在一个驱动调用另一个驱动代码时比较常见,这样模块和模块之间就形成了依赖关系,使用导出符号的模块将会依赖于导出符号的模块。

举个具体的例子,下面是两个C文件,vser.c调用了dep.c中的变量和函数:

vser.c

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

extern int expval;
extern void expfun(void);

static int __init vser_init(void)
{
 printk("vser_init");
 printk("expval:%dn", expval);
 expfun();
 
 return 0;
}

static void __exit vser_exit(void)
{
 printk("vser_exitn");
}

module_init(vser_init);
module_exit(vser_exit);

dep.c

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

static int expval = 5;
EXPORT_SYMBOL(expval);

static void expfun(void)
{
 printk("expfun");
}EXPORT_SYMBOL_GPL(expfun);

Makefile关键处:

obj-m := vser.o
obj-m += dep.o

上述代码中,dep.c定义了一个变量expval和一个函数expfun,并分别用EXPORT_SYMBOLEXPORT_SYMBOL_GPL导出。而vser.c里则调用了dep.c的变量和函数,编译安装后:

# modprobe vser
# dmesg
[58278.204677] vser_init
[58278.204683] expval:5
[58287.206464] expfun

从输出信息中可以看到,vser.c正确引用到了dep.c的变量和函数。

这里有三点重要说明:

  • 如果使用insmod命令加载模块,则必须先加载dep模块,再加载vser模块

因为vser模块用到了dep模块的东西。从这里可以看出,modprobe命令优于insmod命令的地方在于其可以自动加载被依赖的模块。而这又要归功于depmod命令,depmod命令会生成模块的依赖信息,保存在/lib/modules/5.10.111-64-generic/modules.dep文件中。其中,5.10.111-64-generic是内核源码版本。查看该文件可以发现vser模块所依赖的模块。

# cat /lib/modules/5.10.111-64-generic/modules.dep
......
extra/vser.ko: extra/dep.ko
extra/dep.ko:
  • 两个模块存在依赖关系,如果分别编译两个模块,会出现类似下面的警告信息,并且即便加载顺序正确,加载也不会成功 :
WARNING: "expfun" [/home/ubuntu/driver/module/vser.ko] undefined!
WARNING: "expval" [/home/ubuntu/driver/module/vser.ko] undefined!

# sudo insmod dep.ko
# sudo insmod vser.ko
insmod:error inserting 'vser.ko': -1 Invalid parameters

这是因为在编译vser模块时在内核的符号表中找不到expvalexpfun的项,而vser模块又完全不知道dep模块的存在。

解决这个问题的方法是将两个模块放在一起编译,或者将dep模块放在内核源码中,先在内核源码下编译完所有的模块,再编译vser模块。

  • 卸载模块时要先卸载vser模块,再卸载dep模块,否则会因为dep模块被vser模块使用而不能卸载

内核将会创建模块依赖关系的链接,只有当依赖于这个模块的链表为空时,模块才能被卸载.

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2486

    浏览量

    46543
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39862
  • Linux
    +关注

    关注

    87

    文章

    10992

    浏览量

    206742
收藏 人收藏

    评论

    相关推荐

    linux 了解内核模块的原理 《Rice linux 学习开发》

    内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间中运行的程序。
    的头像 发表于 07-16 10:08 4412次阅读
    linux 了解<b class='flag-5'>内核模块</b>的原理 《Rice linux 学习开发》

    Linux 内核模块工作原理及内核模块编译案例

    一个内核模块至少包含两个函数,模块被加载时执行的初始化函数init_module()和模块被卸载时执行的结束函数cleanup_module()。
    发表于 09-23 09:39 2298次阅读
    Linux <b class='flag-5'>内核模块</b>工作原理及<b class='flag-5'>内核模块</b>编译案例

    让ChatGPT写一个内核模块

    笔者最近看到这样一篇文章 ,原作者让 ChatGPT 写一个内核模块,要求实现的功能是:每 5 秒向控制台打印一句 "Hello world",并且把编译需要的 Makefile 也一起写出来。
    发表于 08-17 09:30 312次阅读

    RZ/G2L Linux系统如何添加新的内核模块

    RZ/G2L Linux系统的镜像基于yocto构建,本篇介绍如何添加新的内核模块
    的头像 发表于 01-04 12:19 941次阅读
    RZ/G2L Linux系统如何添加新的<b class='flag-5'>内核模块</b>

    Linux内核模块程序结构

    Linux设备驱动会以内核模块的形式出现,因此,学会编写Linux内核模块编程是学习Linux设备驱动的先决条件。一个Linux内核模块主要由如下几个部分组成: (1)模块加载函数(一
    发表于 05-27 09:36

    Linux内核模块简介

    :用来显示当前系统中所有正在运行的模块信息。4.ksyms:用来显示内核符号和模块符号表信息。5.depmod:处理可加载内核模块依赖关系
    发表于 08-22 09:22

    《Linux设备驱动开发详解》第4章、Linux内核模块

    《Linux设备驱动开发详解》第4章、Linux内核模块
    发表于 10-27 14:15 0次下载
    《Linux设备驱动开发详解》第4章、Linux<b class='flag-5'>内核模块</b>

    内核模块的原理以及其模块编写

    内核模块是具有独立功能的程序。它可以被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间中运行。
    的头像 发表于 01-02 11:11 4172次阅读
    <b class='flag-5'>内核模块</b>的原理以及其<b class='flag-5'>模块</b>编写

    什么是内核模块?如何编写一个简单的模块

    内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),我们简称为模块。Linux
    发表于 08-24 17:15 20次下载

    什么是 Linux 内核模块?

    lsmod 命令能够告诉你当前系统上加载了哪些内核模块,以及关于使用它们的一些有趣的细节。
    的头像 发表于 08-09 17:01 2987次阅读

    嵌入式LINUX系统内核内核模块调试教程

    本文档的主要内容详细介绍的是嵌入式LINUX系统内核内核模块调试教程。
    发表于 11-06 17:32 21次下载
    嵌入式LINUX系统<b class='flag-5'>内核</b>和<b class='flag-5'>内核模块</b>调试教程

    Asterisk内核模块介绍

    主要阐述Asterisk内核模块的基础知识。
    发表于 03-17 13:47 7次下载

    嵌入式LINUX系统内核内核模块调试

    嵌入式LINUX系统内核内核模块调试(嵌入式开发和硬件开发)-嵌入式LINUX系统内核内核模块调试                 
    发表于 07-30 13:55 9次下载
    嵌入式LINUX系统<b class='flag-5'>内核</b>和<b class='flag-5'>内核模块</b>调试

    什么是内核模块签名?内核如何开启模块签名

    驱动可以直接编译进内核镜像,也可以单独编译成ko文件(内核模块),然后再进行加载。内核从3.7后开始支持模块签名,该功能使能以后,内核只允许
    发表于 08-08 16:14 852次阅读

    深入分析Linux kernel安全特性: 内核模块签名

    顾名思义,在开启该功能之后,内核在加载内核模块时,会对内核模块的签名进行检查。
    的头像 发表于 10-18 12:32 1788次阅读