精华内容
下载资源
问答
  • Android 内核模块存放位置

    千次阅读 2017-09-23 16:19:39
    如题:/system/lib/modules/

    如题:

    /system/lib/modules/
    展开全文
  • Linux内核模块管理

    2021-01-20 14:51:10
     2.9.1 内核模块存放位置  Linux内核模块文件的命名方式通常为<模块名称.ko>,CentOS 6.3系统的内核模块被集中存放在/lib/modules/`uname -r`/[1]目录下(uname -r获得的信息为当前内核
  • Linux下内核模块允许我们方便地删除和重新载入内核代码,而卸载内核模块也可以通过命令来实现。下面由学习啦小编为大家整理linux卸载内核模块命令的相关知识,希望对大家有帮助!Linux内核模块介绍:尽管Linux是"单块...

    Linux下内核模块允许我们方便地删除和重新载入内核代码,而卸载内核模块也可以通过命令来实现。下面由学习啦小编为大家整理linux卸载内核模块命令的相关知识,希望对大家有帮助!

    db7c19cbdaf1fd4a3241c81045ebb7a6.png

    Linux内核模块介绍:

    尽管Linux是"单块内核“(monolithic)的操作系统--这是说整个系统内核都运行于一个单独的保护域中,但是linux内核是模块化组成的,它允许内核在运行时动态地向其中插入或从中删除代码。这些代码(包括相关的子线程、数据、函数入口和函数出口)被一并组合在一个单独的二进制镜像中,即所谓的可装载内核模块中,或简称为模块。支持模块的好处是基本内核镜像尽可能的小,因为可选的功能和驱动程序可以利用模块形式再提供。模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。而且当热插拔新设备时,可通过命令载入新的驱动程序。

    linux卸载内核模块命令

    modprobe 不需要指定路径,它会到默认路径下寻找模块。模块也存在依赖性问题: 比如你要加载msdos.ko, 需要先加载fat.ko. modprobe查看/lib/module/version/modules.dep得知模块的依赖关系

    modeprove [-lcfr] module_name

    -c :列出目前系统所有的模块

    -l :列出目前在/lib/modules/`uname -r`/kernel当中的所有模块完整文件名

    -f:强制加载该模块

    -r:类似rmmod 就是删除某个模块

    相关阅读:Linux常用基本命令

    文件名--test

    mkdir test 创建一个文件夹

    mkdir test/test1/test2 -p 在创建test1时候,继续创建test2目录,一起创建

    mv test test1 修改文件名称

    mv test /位置 复制文件到指定位置

    cat test 查看文件内容

    unzip 解压包 解压当前文件

    unzip 解压包 -d /位置 解压压缩包到指定位置

    rm test 删除一个文件

    rm -rf test 删除一个带文件或者文件夹的 文件目录

    cp test test1 复制一个文件

    cp -r test test1 复制一个文件夹(包含文件夹下的文件)

    vi 文件名 修改文件内容

    按i键,下方出现insert,开始编辑内容

    编辑完内容,按esc,退出编辑模式

    :wq 保存退出

    :q! 不保存文件退出

    启动报错,给权限

    chmod 777 ./startup.sh

    chmod -R 777 catalina.sh

    重启nginx: 进入到nginx的sbin目录,重启: ./nginx -s reload(也意指在不关机的情况下,刷新配置文件)

    启动nginx: 进入到nginx的sbin目录,命令./nginx 开启服务

    展开全文
  • Linux内核模块基础--内核模块

    千次阅读 2020-03-24 00:58:36
    下面我们通过编写一个简单的内核模块直接获取当前系统时间。 1.1模块源码编写 在Linux内核源码中,定义了一个struct timeval结构体,结构体中有两个成员变量tv_sec,tv_usec,分别保存当前系统时间的秒和毫秒,...

    1. 内核简单模块的编写

    通过命令date可以获取当前系统时间,如下面示例。

    下面我们通过编写一个简单的内核模块直接获取当前系统时间。

    1.1模块源码编写

    在Linux内核源码中,定义了一个struct timeval结构体,结构体中有两个成员变量tv_sec,tv_usec,分别保存当前系统时间的秒和毫秒,time_t和suseconds_t类型变量在x86架构中,均为long型,变量类型定义在文件include/linux/time.h中。

    00018: struct timeval {

    00019time_t tv_sec/ * seconds */

    00020suseconds_t tv_usec; / * microseconds */

    00021: };

    00022:

     

    模块源码如下:

    00001:

    00002: #include <linux/ module.h>

    00003: #include <linux/ time.h>

    00004:

    00005: static char modname[] = "time";

    00006:

    00007: extern struct timespec xtime;

    00008:

    00009: int init_module( void )

    00010: {

    00011struct timeval tv;

    00012printk( "Installing %s module.", modname );

    00013do_gettimeofday(&tv);

    00014printk("\njiffies:%lu, tv.tv_sec:%lu, tv.tv_nsec:%lu ", jiffies, tv.tv_sec, tv.tv_usec);

    00015:

    00016return 0;

    00017: }

    00018:

    00019:

    00020: void cleanup_module( void )

    00021: {

    00022printk( "\nRemoving %s module.", modname );

    00023: }

    00024:

    00025: MODULE_LICENSE("GPL");

    00026:

     

    1.2Makefile

    创建一个Makefile,执行make,即可编译生成内核模块,生成后缀名为.ko的文件。

    Makefile内容:

    注意:在default:后面的$(MAKE) … … 和rm –r … …两行前面必须是Tab键,不能为空格或其他字符,否则执行make时,会报告“Makefile:10: *** missing separator. Stop.”错误。

    1.3模块加载

    执行make,编译生成模块.ko文件后,就可以通过insmod命令来加载模块。

    通过lsmod命令可以查看驱动是否成功加载到内核中。

    通过insmod命令加载刚编译成功的time.ko模块后,似乎系统没有反应,也没看到打印信息。而事实上,内核模块的打印信息一般不会打印在终端上。驱动的打印都在内核日志中,我们可以使用dmesg命令查看内核日志信息。

    内核模块time.ko获取到的当前系统时间为1289489871秒,与执行date ‘+%s’命令获取到的值一致。

    2内核模块版本与符号表

    在编写和使用内核模块过程中,会发现在某个内核版本上编译的模块只能在当前内核版本中使用。若模块版本号与当前内核版本号不匹配导致就会无法加载,提示“insmod: error inserting 'time.ko': -1 Invalid module format”,内核会打印类似信息“time: version magic '2.6.32.12-0.7-default SMP mod_unload modversions ' should be '2.6.18-92.el5 SMP mod_unload gcc-4.1'”。

    2.1内核模块版本号

    查看内核模块版本信息的命令为modinfo,如查看刚才我们编写的time.ko。

    模块的版本号在“vermagic“一项,当前系统中使用的模块版本号都是相同的。

    模块版本号是哪里决定的?我们是否可以更改?我们是否可以在当前系统中,编译其他内核版本的模块?

    2.1.1模块版本号的确定

    在make编译模块时,通过-C参数制定内核源码头文件位置。前面我们编译time模块内核源码头文件位置为/lib/modules/2.6.32.12-0.7-default/build。

    make -C /lib/modules/2.6.32.12-0.7-default/build SUBDIRS=/root/programming modules

    我们来分析模块版本号的确定

    vermagic: 2.6.32.12-0.7-default SMP mod_unload modversions

    在RHEL5系统中,模块版本号vermagic由include/linux/vermagic.h和include/linux/utsrelease.h两个文件的内容来决定,即vermagic就为VERMAGIC_STRING

    文件include/linux/utsrelease.h的内容如下:

    文件include/linux/vermagic.h的内容如下:

    而在SLES11.1内核2.6.32.12-0.7-default的模块版本号VERMAGIC_STRING由scripts/mod/modpost可执行文件确定。

    2.1.2模块版本号的修改

    前面分析了模块版本号由VERMAGIC_STRING确定产生,若我们需要修改模块版本号或希望在当前内核版本中编译其他内核的模块(注意gcc大版本和CPU架构i686/x86_64保持一致),只需要修改控制模块的VERMAGIC_STRING值即可。

    如我们将示例中的time模块在RHEL5.2内核中编译RHEL5.3内核模块,然后在RHEL5.3系统上可以加载。

    2.1.3编译非当前内核版本模块

    在模块版本号的修改介绍的方法中,仅适合内核版本(OS发行版本)差别不大的情况下,可以方便修改某块版本。本小节介绍如何编译非当前内核版本模块。

    步骤:

    1. 将待编译特定内核源码开发包拷贝到当前系统中某个目录下

    如我们打算在SLES11.1 x86_64系统中编译RHEL5.5 x86_64内核模块,应先将RHEL5.5 x86_64内核开发包拷贝到SLES11.1系统中。

    1. 修改Makefile,将KDIR指向待编译内核开发包目录

    在Makefile中,设置KDIR变量为指定内核源码目录位置。

    3、执行make编译模块

    执行后,生成内核模块。可以使用modinfo命令来查看新生成模块的版本号。如

    #modinfo /root/programming/time.ko

     

    编译非当前内核版本模块后,加载再次提示“Invalid module format”时,通过dmesg命令查看加载失败原因。

    如上面的提示,我们直接include/linux/vermagic.h文件即可,将gcc版本信息值改为固定值gcc-4.1即可。

    2.2内核符号表及使用

    加载模块时,insmod使用公共内核符号表解析模块中未定义的符号。公共符号表中包含了所有的全局内核项(即函数和变量)的地址,内核符号表的内容全部在文件/proc/kallsyms中,可以通过cat等命令查看。内核和模块将函数、变量导出后,就成为内核符号表的一部分。

    在我们编写的内核模块中,可以使用内核或其他模块定义的函数和变量,如本章示例的获取时间模块中,就调用了内核函数do_gettimeofday()。

     

    内核中有两个宏用来导出函数和变量:

    EXPORT_SYMBOL(symbolname)

    将函数或变量导出到所有模块

    EXPORT_SYMBOL_GPL(symbolname)

    将函数或变量仅导出到GPL模块

    我们也可以在自己的模块中导出部分函数或变量,这样其他模块就可以访问这部分函数、变量。C语言用户态程序编程中,我们常会使用在其他C文件或lib库中定位的函数和变量,内核符号表和这有相似之处。

    系统中所有内核和模块导出的变量和函数,就成了内核符号表,在/proc/kallsyms文件中。

    内核符号表中,第一列为函数或变量的在内核中的地址,第二列为符号的类型,第三列为符号名,第四列为符号所属的模块。若第四列为空,则表示该符号属于内核代码。

    内核符号属性

    符号属性

    含义

    b

    符号在未初始化数据区(BSS)

    c

    普通符号,是未初始化区域

    d

    符号在初始化数据区

    g

    符号针对小object,在初始化数据区

    i

    非直接引用其他符号的符号

    n

    调试符号

    r

    符号在只读数据区

    s

    符号针对小object,在未初始化数据区

    t

    符号在代码段

    u

    符号未定义

     

    若符号在内核中是全局性的,则属性为大写字母,如T、U等。其他符号属性含义,请参考命令nm的帮助信息。

    00273: / * Only label it "global" if it is exported. */

    00274: static void upcase_if_global(struct kallsym_iter *iter)

    00275: {

    00276if (is_exported(iter- >name, iter- >owner))

    00277iter- >type += 'A' - 'a';

    00278: }

    00279:

     

    若打算使用内核中的符号,在模块中增加函数或变量说明即可。如:

    00091: extern struct timespec xtime;

     

    3模块版本控制

    Linux内核版本在不变升级,内核提供的API或符号可能也随之变化。这对内核模块开发来说,是一个比较麻烦的问题,通常要适应不同的内核版本,或者只针对具体某些内核版本开发。

    内核为了确保模块的函数接口与内核借口一致,采用了模块版本控制。版本控制最简单的办法就是为了内核和模块都设置一个常量,该常量会随着接口变化而不断增加。加载模块时,内核会检查模块提供的常量是否和内核版本常量相等,若不相等则拒绝加载。

    采用常量的办法进行版本控制,方法简单,但不够灵活。如内核部分接口变化后,版本常量就会增加。但若某模块使用的这些接口并没有变化,也会导致驱动无法加载。基于这个原因,最恰当的方法是将单个内核API的变化考虑进去。实际的模块和内核实现无关,模块和内核关系密切的是API接口。

    3.1checksum方法

    CRC checksum原理是使用函数的参数来计算校验码,若校验码不相等,加载模块失败。

    我们来看一下内核执行模块加载的函数load_module()(文件kernel/module.c)。1767行会调用check_modstruct_version()函数来检查struct_module符号的CRC校验码。若校验码不相等,则提示“disagrees about version of symbol struct_module”。如

    hwinc_kernel_driver: disagrees about version of symbol struct_module

    Found checksum B6AF205C vs module F3D5F8AF

     

    01600: static struct module *load_module(void __user *umod,

    01601unsigned long len,

    01602const char __user *uargs)

    01603: {

    01604Elf_Ehdr *hdr;

    01605Elf_Shdr *sechdrs;

    … …

    01766/ * Check module struct version now, before we try to use module. */

    01767if (! check_modstruct_version(sechdrs, versindex, mod)) {

    01768err = - ENOEXEC;

    01769goto free_hdr;

    01770}

    01771:

    01772modmagic = get_modinfo(sechdrs, infoindex, "vermagic");

    01773/ * This is allowed: modprobe - - force will invalidate it. */

    01774if (! modmagic) {

    01775add_taint_module(mod,TAINT_FORCED_MODULE);

    01776printk(KERN_WARNING "%s: no version magic, tainting

    kernel.\n",

    01777mod- >name);

    01778else if (! same_magic(modmagic, vermagic )) {

    01779printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",

    01780mod- >name, modmagic, vermagic );

    01781err = - ENOEXEC;

    01782goto free_hdr;

    01783}

     

    在编译内核模块时,会生成*.mod.c文件,该文件中包含了模块中各个符号的校验码。校验码的生成,由scripts/genksyms/genksyms计算生成。

    注意:scripts/genksyms/genksyms文件是在内核源码目录或内核开发包目录中,如/usr/src/linux-2.6.32.12-0.7-obj/x86_64/default/scripts/genksyms/genksyms

    3.2vermagic

    查看内核版本模块信息时,会看到vermagic一项。模块在装载时,load_module()函数会比较(如前面代码的1772行)当前运行内核的vermagic和当前要加载的模块的vermagic比较,如果不同,则禁止加载模块。

    Vermagic的的确定请参考章节2.1.1。

    3.3内核模块版本控制使能与关闭

    我们常遇到内核提示“disagrees about version of symbol struct_module”,而导致模块无法加载的情况。

    3.3.1内核中关闭/使能

    若选择关闭内核的模块版本控制功能,则会避免出现这种情况。模块版本控制选项在内核源码配置文件.config中,注释掉CONFIG_MODVERSIONS就取消了模块版本控制。

    CONFIG_MODVERSIONS=y

    重新编译内核,重启即可。

    3.3.2模块中关闭/使能版本控制

    如下面的实例。虽然模块的vermagic和内核一致,但struct_module的版本号不一致。我们可以不修改当前内核,重新编译模块即可解决问题。

    若去掉模块版本控制后,加载驱动导致系统死机。建议解决办法:使用待运行内核的.config配置文件覆盖模块编译指向的内核开发包(源码).config文件。

    .config配置文件的获取:(1)可以拷贝/proc/config.gz,然后解压缩,拷贝为.config;(2)若/proc/config.gz不存在,可以使用/boot/目录下对应的内核配置文件;(3)或向内核提供者获取.config配置文件。

    此时我们可以修改内核开发包中的模块版本控制选项,修改文件.config(在内核源码或开发包根目录下),注释掉或删除CONFIG_MODVERSIONS选项,重新编译模块即可去除模块的版本控制。

    CONFIG_MODULES=y

    CONFIG_OBSOLETE_MODPARM=y

    #CONFIG_MODVERSIONS=y

    CONFIG_MODULE_SIG=y

    4内核模块参数

    在用户执行系统命令或其他程序时,可以使用参数。内核模块也可以使用参数。

    参数必须使用宏module_param()声明,该宏定义在include/linux/moduleparam.h文件中。module_param()需要三个参数:参数名称、类型、sysfs文件系统入口项的访问权限掩码。

    模块参数的定义必须放在任何函数之外。如本章获取系统时间的模块示例,我们增加province和population两个参数(参数仅作示范,和系统时间无任何关系)。

    00001: #include <linux/ module.h>

    00002: #include <linux/ time.h>

    00003: #include <linux/ moduleparam.h>

    00004:

    00005: static char modname[] = "time";

    00006:

    00007: static char *province = "Guangdong";

    00008: module_param(provincecharp0);

    00009: static int population = 10000;

    00010: module_param(populationint0);

    00011:

    00012: int init_module( void )

    00013: {

    00014struct timeval tv;

    00015printk( "Installing %s module.", modname );

    00016do_gettimeofday(&tv);

    00017printk("\njiffies:%lu, tv.tv_sec:%lu, tv.tv_nsec:%lu ",

    00018jiffies, tv.tv_sec, tv.tv_usec);

    00019:

    00020printk("\nProvince:%s, Population:%d \n", province , population );

    00021:

    00022return 0;

    00023: }

    00024:

    00025:

    00026: void cleanup_module( void )

    00027: {

    00028printk( "\nRemoving %s module.", modname );

    00029: }

    00030:

    00031: MODULE_LICENSE("GPL");

    00032:

     

    加载模块time后,内核打印信息:

    内核模块支持的参数类型如下:

    bool

    invbool

    charp:字符串指针。内核会为用户提供的字符串自动分配内存。

    int

    long

    short

    uint:unsigned int

    ulong:unsigned long

    ushort:unsigned short

    5模块入口/出口函数及其他

    每个内核模块都要有初始化(入口)函数和清除(出口)函数,清除函数负责在模块被移除前注销接口并向系统返回所有资源。

    在本章time模块的示例中,并没有像用户态C程序一样有main()入口函数。time模块入口函数为init_module(),而出口函数为cleanup_module()。

    在复杂的模块中,我们可以指定模块的入口/出口函数名称。通过module_init()和module_exit()函数分别指定。如LSISAS1068E驱动mptsas中的入口/出口函数:

    04828: module_init(mptsas_init);

    04829: module_exit(mptsas_exit);

    在模块中,我们还可以添加作者信息、模块描述、模块版本等信息。

    MODULE_AUTHOR():模块作者信息

    MODULE_DESCRIPTION():模块描述

    MODULE_LICENSE():模块协议

    MODULE_VERSION():模块版本

    如:

    00070: #define my_NAME "Fusion MPT SCSI Host driver"

    00071: #define my_VERSION MPT_LINUX_VERSION_COMMON

    00072: #define MYNAM "mptscsih"

    00073:

    00074: MODULE_AUTHOR(MODULEAUTHOR);

    00075: MODULE_DESCRIPTION(my_NAME);

    00076: MODULE_LICENSE("GPL");

    00077: MODULE_VERSION(my_VERSION);

     

    6内核模块与用户程序区别

    6.1用户空间与内核空间

    内核空间具有最高权限,可以访问所有CPU寄存器和其他所有资源。

    • 内核空间可以访问所有的CPU指令和所有的内存空间、I/O空间。

    • 用户空间只能访问有限的资源,若需要特殊权限,可以通过系统调用获取相应的资源。

    • 用户空间允许页面中断,而内核空间则不允许。

    • 用户空间是0-3G的地址范围,内核空间是3G-4G的地址范围。

    • 内核空间和用户空间是针对线性地址空间的。

    • 所有内核进(线)程共用一个地址空间,而用户进程都有各自的地址空间。

    ​​​​​​​                                                               Linux 32位系统用户空间与内核空间

    6.2内核模块与应用程序的对比

    • 内核模块具有独立的地址空间

    模块运行在内核空间中。应用程序运行在用户空间中。系统软件受到保护,不允许用户程序访问。内核空间和用户空间有各自独立的内存地址空间。

    • 内核模块具有更高的执行特权

    运行在内核空间中的代码要比运行在用户空间中的代码具有更大的特权。

    • 内核模块不按顺序执行

    用户程序通常按顺序执行并且从头到尾地执行单独的任务。内核模块并不按顺序执行,它注册自己是为了服务将来的请求。

    • 内核模块可以被中断

    在同一时刻,可能有许多进程同时向驱动程序发出请求。中断程序可以在驱动程序正在响应系统调用时,向驱动程序发出请求。在对称多处理器(SMP)系统中,驱动程序可能在多个 CPU 上并发地执行。

    • 内核模块必须是可抢占的

    • 内核模块能够共享数据

    一个应用程序的不同线程常常不会共享数据。与之相对应的是,组成驱动程序的数据结构和例程被所有使用驱动程序的线程所共享。驱动程序必须能够处理由多个请求导致的竞争问题。

    • 错误处理

    应用程序的错误导致Segmentation Fault,而内核模块的错误影响整个系统,甚至使内核

    7常见问题处理

    1、头文件引用

    在用户程序和内核模块时,可能都会使用头文件 #include <linux/time.h>,但两者文件所在的位置是不同的。

    用户态用户程序使用的time.h,在gcc库文件中,一般位置是/usr/include/linux/time.h或/usr/include/sys/time.h。

    内核模块使用的time.h,在内核源码头文件中,一般位置是<内核版本>/include/linux/time.h,如/usr/src/kernels/2.6.18-128.el5-x86_64/include/linux/time.h。

     

    2、提示内核build目录不存在

    在编写好内核模块后,执行make时,有的系统会提示类似“make: *** /lib/modules/2.6.18-128.el5xen/build: No such file or directory. Stop.”错误信息。原因在于内核源码开发包没有安装。

    解决办法:安装当前内核版本的源码开发包。

    3、模块加载提示Invalid Module Format”

    解决步骤:

    1. 执行dmesg命令,查看模块提示Invalid Module Format的详细原因

    2. 根据提示信息,结合本章提到内核模块版本号与修改一些,修复相应的错误。

    4、模块加载提示“Symbol not found”

    解决步骤:

    1. 执行dmesg命令,查看模块哪些符号在当前系统中不存在。

    2. 执行modinfo命令,查看当前模块依赖关系,并检查依赖的模块是否已加载到系统中。

    4、模块加载提示“disagrees about version of symbol struct_module

    请参考“模块版本控制”一节。

    5、是否有办法将模块加载到非当前内核版本中,而不重新编译模块?

    在内核版本相近和CPU架构相同的情况下,如2.6.18-92.e15 i686和2.6.18-194.e15 i686内核,可以直接二进制编辑模块,修改模块的版本信息,这样就可以加载到非当前内核版本中了。

     

    展开全文
  • linux如何卸载内核模块 本文摘自Manning出版的《 Linux in Action》第15章。 Linux使用内核模块管理硬件外围设备。 这是这样的。 一个运行中的Linux内核是您不想烦恼的事情之一。 毕竟,内核是驱动计算机执行...

    linux如何卸载内核模块

    本文摘自Manning出版的《 Linux in Action》第15章。

    Linux使用内核模块管理硬件外围设备。 这是这样的。

    一个运行中的Linux内核是您不想烦恼的事情之一。 毕竟,内核是驱动计算机执行所有操作的软件。 考虑到必须在实时系统上同时管理多少个细节,最好让内核以尽可能少的干扰来完成其工作。 但是,如果在不重新启动整个系统的情况下无法对计算环境进行很小的更改,则插入新的网络摄像头或打印机可能会给您的工作流程带来痛苦。 每次添加设备时都必须重新启动,以使系统识别它几乎没有效率。

    为了在稳定性和可用性的对立优点之间取得有效的平衡,Linux隔离了内核,但允许您通过可加载的内核模块(LKM)快速添加特定的功能。 如下图所示,您可以将模块视为一个软件,它告诉内核在哪里可以找到设备以及如何使用该设备。 反过来,内核使设备可供用户和进程使用,并监督其运行。

    Kernel modules

    内核模块充当设备和Linux内核之间的转换器。

    没有什么可以阻止您编写自己的模块以完全按照您希望的方式支持设备的,但是为什么要麻烦呢? Linux模块库已经非常强大,以至于通常不需要自己动手。 在绝大多数情况下,Linux会自动加载新设备的模块,而您甚至都不知道它。

    尽管如此,由于某些原因,有时它并不是单独发生的。 (您不想让招聘经理不耐烦地等待您的笑脸加入视频会议工作面试时间太长。)为了帮助您完成工作,您需要对内核模块有更多的了解,尤其是,如何找到将运行外围设备的实际模块,然后如何手动激活它。

    查找内核模块

    按照公认的惯例,模块是扩展名为.ko(内核对象)的文件,位于/lib/modules/目录下。 但是,在完全导航到这些文件之前,您可能必须做出选择。 因为在启动时可以从版本列表中加载一个选项,所以支持选择的特定软件(包括内核模块)必须存在于某个地方。 好吧, /lib/modules /就是其中之一。 在该目录中,您可以找到每个可用Linux内核发行版的模块填充目录; 例如:

    
       
    $ ls /lib/modules
    4.4.0-101-generic
    4.4.0-103-generic
    4.4.0-104-generic

    就我而言,活动内核是具有最高发行版本号(4.4.0-104通用)的版本,但不能保证对您而言会是相同的(内核会经常更新)。 如果要对要在实时系统上使用的模块进行某些工作,则需要确保您拥有正确的目录树。

    uname -r-r从通常会显示的系统信息中指定内核发行版号):
    
       
    $ uname -r
    4.4.0-104-generic

    有了这些信息,您可以使用称为命令替换的过程将uname合并到文件系统引用中。 例如,要导航到正确的目录,请将其添加到/lib/modules 。 要告诉Linux“ uname”不是文件系统位置,请将uname部分括在反引号中,如下所示:

    
       
    $ ls /lib/modules/`uname -r`
    build   modules.alias        modules.dep      modules.softdep
    initrd  modules.alias.bin    modules.dep.bin  modules.symbols
    kernel  modules.builtin      modules.devname  modules.symbols.bin
    misc    modules.builtin.bin  modules.order    vdso

    您将在kernel/目录下的子目录中找到大多数模块。 花几分钟时间浏览这些目录,以了解事物的排列方式和可用的内容。 文件名通常可以使您很好地了解所要查找的内容。

    
       
    $ ls /lib/modules/`uname -r`/kernel
    arch  crypto  drivers  fs  kernel  lib  mm
    net  sound  ubuntu  virt  zfs

    这是定位内核模块的一种方法。 实际上,这是快速而肮脏的方法。 但这不是唯一的方法。 如果要获取完整的集合,可以使用lsmod列出所有当前加载的模块以及一些基本信息。 截断的输出的第一列(此处列出的内容太多了)是模块名称,然后是文件大小和编号,然后是每个模块所依赖的其他模块的名称:

    
       
    $ lsmod
    [...]
    vboxdrv          454656  3 vboxnetadp,vboxnetflt,vboxpci
    rt2x00usb        24576  1 rt2800usb
    rt2800lib        94208  1 rt2800usb
    [...]

    多少太多? 好吧,让我们再次运行lsmod ,但这一次将输出管道传输到wc -l以获得行数:

    
       
    $ lsmod | wc -l
    113

    这些是已加载的模块。 总共有多少个可用? 运行modprobe -c并计算行数将得到该数字:

    
       
    $ modprobe -c | wc -l
    33350

    共有33,350个可用模块! 多年来,似乎有人一直在努力为我们提供运行物理设备的软件。

    注意:在某些系统上,您可能会遇到在/etc/modules文件中以其唯一条目引用的定制模块,或者将其作为配置文件保存到/etc/modules-load.d/ 。 这样的模块很可能是本地开发项目的产品,可能涉及尖端的实验。 无论哪种方式,最好都对正在查看的内容有所了解。

    这就是找到模块的方式。 您的下一个工作是弄清楚如果由于某种原因它不是独立发生的,则如何手动加载不活动的模块。

    手动加载内核模块

    在加载内核模块之前,逻辑要求您必须确认它的存在。 在执行此操作之前,您需要知道它的名称。 有时候,获得这一部分需要同等的魔力和运气,以及在线文档作者的辛勤工作中的一些帮助。

    我将通过描述一段时间后遇到的问题来说明该过程。 晴朗的一天,由于仍然无法摆脱我的原因,笔记本电脑上的WiFi接口停止工作。 就这样 也许是软件更新将其淘汰了。 谁知道? 我运行了lshw -c network ,并得到了以下非常奇怪的信息:

    
       
    network UNCLAIMED
        AR9485 Wireless Network Adapter

    Linux识别了该接口(Atheros AR9485),但将其列为无人认领。 就像他们说的那样:“当艰难时,艰难地搜索互联网。” 我搜索了atheros ar9 linux模块 ,在浏览了5年甚至10年历史的页面并建议我写自己的模块或放弃时,我终于发现了这一点(使用Ubuntu 16.04,至少)存在一个工作模块。 它的名字是ath9k。

    是! 战斗和胜利一样好! 向内核添加模块比听起来容易得多。 要再次检查它是否可用,可以针对模块的目录树运行find ,指定-type f告诉Linux您正在寻找文件,然后添加字符串ath9k以及glob星号以包括所有以开头的文件名您的字符串:

    
       
    $ find /lib/modules/$(uname -r) -type f -name ath9k*
    /lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_common.ko
    /lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k.ko
    /lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_htc.ko
    /lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_hw.ko

    仅需一步,即可加载模块:

     # modprobe ath9k 
    

    而已。 没有重启。 别大惊小怪。

    这是另一个示例,向您展示如何使用已损坏的活动模块。 曾经有一段时间,将我的Logitech网络摄像头与特定软件一起使用会使该摄像头无法被任何其他程序访问,直到下次启动系统为止。 有时,我需要在其他应用程序中打开相机,但没有时间关闭并重新启动。 (我运行了许多应用程序,在启动后将它们全部安装到位需要一些时间。)

    因为此模块可能处于活动状态,所以使用lsmod搜索单词video应该给我有关相关模块名称的提示。 实际上,它总比提示好:用video一词描述的唯一模块是uvcvideo (如下所示):

    
       
    $ lsmod | grep video
    uvcvideo               90112  0
    videobuf2_vmalloc      16384  1 uvcvideo
    videobuf2_v4l2         28672  1 uvcvideo
    videobuf2_core         36864  2 uvcvideo,videobuf2_v4l2
    videodev              176128  4 uvcvideo,v4l2_common,videobuf2_core,videobuf2_v4l2
    media                  24576  2 uvcvideo,videodev

    我可能已经控制了导致崩溃的某些事情,我想我可能已经更深入地研究了一下是否可以正确地解决问题。 但是你知道这是怎么回事。 有时您不关心理论,只希望设备正常工作。 因此,我使用rmmod杀死了uvcvideo模块,并使用modprobe再次重新启动了它:

    
       
    # rmmod uvcvideo
    # modprobe uvcvideo

    再次:没有重启。 没有顽固的血迹。

    翻译自: https://opensource.com/article/18/5/how-load-or-unload-linux-kernel-module

    linux如何卸载内核模块

    展开全文
  • Linux内核模块在形式上以.ko文件存在,首先需要知道的是内核模块的编译也分为动态编译和静态编译,动态编译模块生成.ko文件。动态模块的加载命令如下:insmod ****.ko,比较常见的是Linxu设备驱动以内核模块的形式...
  • 众所周知,Linux内核分为几个模块,这样既方便管理,也可以方便增加新...Linux一、内核模块存放位置Linux内核模块文件的命名方式通常为,CentOS 6.3系统的内核模块被集中存放在/lib/modules/`uname -r`/[1]目录下...
  • Linux内核模块详解

    万次阅读 多人点赞 2019-08-26 09:22:36
    内核模块 实验目的 内核模块是Linux操作系统中一个比较独特的机制。通过这一章学习,希望能够理解Linux提出内核模块这个机制的意义;理解并掌握Linux实现内核模块机制的基本技术路线;运用Linux提供的工具和命令,...
  • 内核模块

    2019-05-31 14:00:21
    1)内核模块存放位置 ]# cd /lib/modules ]# ls 3.10.0-123.el7.x86_64 ]# cd 3.10.0-123.el7.x86_64/ ]# ls build modules.block modules.devname modules.softdep vdso extra ...
  • 文章目录内核模块实验 Hello World前提配置程序编写编译与加载内核符号表初始化与清理函数hello world 模块加载举例内核模块机制的实现模块在内核中的表示模块的加载与卸载模块的加载模块的卸载内核模块显示进程控制...
  • 记录编写一个简单的内核模块

    千次阅读 2019-07-05 15:30:40
    //任何模块都必须包含,定义了可动态加载到内核模块所需要的必要信息 # include <linux/init.h> //必须包含,包含了宏__init(指定初始化函数)和__exit(指定清除函数) # include <linux/kernel....
  • linux内核模块的参数传递

    千次阅读 2019-06-26 22:33:02
    带参数的模块安装后会生成目录: /sys/module/模块名/parameters/ 示例:如果安装 了名字为 hello_model_param 的模块,则会生成 /sys/module/hello_model_param/parameters/ 这个文件夹下会生成...
  • Linux内核模块开发

    2019-06-03 21:38:51
    1.LINUX内核模块基础 1.1 什么是内核模块? Linux内核的整体结构非常庞大,其包含的组件也非常多,如何使用这些组件呢?方法1:把所有的组件都编译进内核文件,即:zImage或bzImage,但这样会导致一个问题:占用...
  • 目录(一)模块化编程简介(二)安装卸载模块命令.(三)将自定义功能添加到内核三种方法(1)修改Kconfig和Makefile(2)直接修改功能对应目录下的Makefile文件(3)在内核目录中,将功能编译成模块文件,后期加载...
  • openwrt中添加自定义内核模块

    千次阅读 2019-02-18 20:11:42
    本文介绍如何在openwrt中增加一个自定义的内核模块包 1、在package/kernel下创建一个应用程序目录mydrv,并在mydrv下再创建一个src用于存放源码文件 $ cd package/kernel $ mkdir mydrv $ cd mydrv $ mkdir src...
  • Linux 内核模块调试方法

    千次阅读 2019-06-05 22:29:07
    Linux 内核模块调试方法 1 lsmod使用方法 1) 查看当前安装的内核模块:lsmod # lsmod Module Size Used by Tainted: G mailbox_test 16384 0 spinor_blk 49152 1 查看当前某个模块是否安装 # lsmod | grep...
  • Linux编写内核模块及文件读写

    万次阅读 2018-01-18 15:44:55
    sysfs是什么sysfs是一个基于内存的文件系统,它的作用是将内核信息以文件的方式提供给用户程序使用。该文件系统的目录层次结构严格按照内核的数据结构组织。除了二进制文件外(只有特殊场合才使用...Linux内核模块是什
  • 内核模块的加载与卸载

    千次阅读 2019-08-19 18:46:11
    2: 内核模块存放位置 /lib/modules/($uname -r)/kernel 3: 模块的依赖性:检查 /lib/modules/($uname -r)/modules.dep文件,它记录了内核支持模块的依赖关系。 .dep文件的制作:通过depmod命令 eg:...
  • 任何偶数的核心(的二个数为偶数,例如2.0.30)都是一个稳定地发行的核心,而任何奇数的核心(例如2.1.42)都是一个开发中的核心核心源程序的文件按树形结构进行组织,在源程序树的最上层,即目录/usr/src/linux下有这样...
  • 内核完成再次系统自检之后,开始采用动态的方式加载每个硬件的模块,这个动态模块大家可以想象成硬件的驱动(默认 Linux 硬件的驱动是不需要手工安装的,如果是重要的功能,则会直接编译到内核当中;如果是非重要的...
  • linux内核模块编译 两种编译

    万次阅读 2018-04-09 18:51:27
    linux内核模块的编译方法有两种: 1.放入linux内核源码中编译。 2.独立编译模块。 (1)放入linux内核源码中编译 这里先了解Kconfig和Makefile的作用 Kconfig:对应内核模块的配置菜单。 Makefile:对应内核...
  • 本篇文章中只讨论linux内核模块编译的makefile,linux内核makefile总览可以参考另一篇博客:linux内核makefile概览 本篇博客参考官方文档。 linux内核使用的是kbuild编译系统,在编译可加载模块时,其makefile的风格...
  • 内核模块的加载

    千次阅读 2015-04-27 17:49:46
    一般linux中有两个程序可以添加内核模块,modprobe和insmod,前者考虑到了各个模块之间可能出现的依赖关系,被依赖的模块会被自动载入,而insmod只是简单的尝试载入当前的模块。二者最终都是通过linux系统调用sys_...
  • 我们首先来看看内核模块的定义。 模块是具有独立功能的程序,可以单独编译,但是不能单独运行。模块在运行时,会被链接到内核,作为内核的一部分在内核空间运行。模块通常由一组函数和数据结构组成,用来实现一种...
  • 静态编译即为将驱动直接编译进内核,动态编译即为将驱动编译成模块。 而动态编译又分为两种: a -- 内部编译  在内核源码目录内编译 b -- 外部编译  在内核源码的目录外编译 二、具体编译过程分析  注:本次...
  • 大纲: 1.交叉编译环境搭建 2.内核模块的编写 3.将开发板连接上PC串口测试,加载模块 4.内核模块参数 5.总结
  • 因为内核模块要和内核源码树中的目标文件进行连接,通过这种方式,可得到一个更加健壮的模块装载器,但也需要这些目标文件存在于内核目录树中。这样,我们就要首先准备好一个内核源代码树,构造一个新内核,然后...
  • Linux内核模块编程指南(一)

    万次阅读 多人点赞 2018-09-02 15:03:56
    翻译来自: http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html Peter Jay Salzman Michael Burian Ori Pomerantz ...2007-05-18 ver 2.6.4 Linux内核模块编程指南是一本免费的书; 您可以根据开放软件许...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 161,436
精华内容 64,574
关键字:

内核模块存放的目录位置是

友情链接: mytest.zip