精华内容
下载资源
问答
  • 什么是 Linux 内核模块内核模块是可以根据需要加载到内核中或从内核中卸载的代码块,因此无需重启就可以扩展内核的功能。事实上,除非用户使用类似 lsmod 这样的命令来查询模块信息,否则用户不太可能知道内核发生...

    lsmod 命令能够告诉你当前系统上加载了哪些内核模块,以及关于使用它们的一些有趣的细节。

    2afff878e583e8f8feb128c9a2f87f72.png

    什么是 Linux 内核模块?

    内核模块是可以根据需要加载到内核中或从内核中卸载的代码块,因此无需重启就可以扩展内核的功能。事实上,除非用户使用类似 lsmod 这样的命令来查询模块信息,否则用户不太可能知道内核发生的任何变化。

    需要知道的重要一点是,在你的 Linux 系统上总会有很多可用的模块,并且如果你可以深入其中了解到很多细节。

    lsmod 的主要用途之一是在系统不能正常工作时检查模块。然而,大多数情况下,模块会根据需要加载的,而且用户不需要知道它们如何运作。

    显示内核模块

    显示内核模块最简单的方法是使用 lsmod 命令。虽然这个命令包含了很多细节,但输出却是非常用户友好。

    $ lsmodModule Size Used bysnd_hda_codec_realtek 114688 1snd_hda_codec_generic 77824 1 snd_hda_codec_realtekledtrig_audio 16384 2 snd_hda_codec_generic,snd_hda_codec_realteksnd_hda_codec_hdmi 53248 1snd_hda_intel 40960 2snd_hda_codec 131072 4 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel ,snd_hda_codec_realteksnd_hda_core 86016 5 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel ,snd_hda_codec,snd_hda_codec_realteksnd_hwdep 20480 1 snd_hda_codecsnd_pcm 102400 4 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda _coresnd_seq_midi 20480 0snd_seq_midi_event 16384 1 snd_seq_mididcdbas 20480 0snd_rawmidi 36864 1 snd_seq_midisnd_seq 69632 2 snd_seq_midi,snd_seq_midi_eventcoretemp 20480 0snd_seq_device 16384 3 snd_seq,snd_seq_midi,snd_rawmidisnd_timer 36864 2 snd_seq,snd_pcmkvm_intel 241664 0kvm 626688 1 kvm_intelradeon 1454080 10irqbypass 16384 1 kvmjoydev 24576 0input_leds 16384 0ttm 102400 1 radeondrm_kms_helper 180224 1 radeondrm 475136 13 drm_kms_helper,radeon,ttmsnd 81920 15 snd_hda_codec_generic,snd_seq,snd_seq_device,snd_hda _codec_hdmi,snd_hwdep,snd_hda_intel,snd_hda_codec,snd _hda_codec_realtek,snd_timer,snd_pcm,snd_rawmidii2c_algo_bit 16384 1 radeonfb_sys_fops 16384 1 drm_kms_helpersyscopyarea 16384 1 drm_kms_helperserio_raw 20480 0sysfillrect 16384 1 drm_kms_helpersysimgblt 16384 1 drm_kms_helpersoundcore 16384 1 sndmac_hid 16384 0sch_fq_codel 20480 2parport_pc 40960 0ppdev 24576 0lp 20480 0parport 53248 3 parport_pc,lp,ppdevip_tables 28672 0x_tables 40960 1 ip_tablesautofs4 45056 2raid10 57344 0raid456 155648 0async_raid6_recov 24576 1 raid456async_memcpy 20480 2 raid456,async_raid6_recovasync_pq 24576 2 raid456,async_raid6_recovasync_xor 20480 3 async_pq,raid456,async_raid6_recovasync_tx 20480 5 async_pq,async_memcpy,async_xor,raid456,async_raid6_re covxor 24576 1 async_xorraid6_pq 114688 3 async_pq,raid456,async_raid6_recovlibcrc32c 16384 1 raid456raid1 45056 0raid0 24576 0multipath 20480 0linear 20480 0hid_generic 16384 0psmouse 151552 0i2c_i801 32768 0pata_acpi 16384 0lpc_ich 24576 0usbhid 53248 0hid 126976 2 usbhid,hid_generice1000e 245760 0floppy 81920 0

    在上面的输出中:

    Module显示每个模块的名称

    Size显示每个模块的大小(并不是它们占的内存大小)

    Used by显示每个模块被使用的次数和使用它们的模块

    显然,这里有很多模块。加载的模块数量取决于你的系统和版本以及正在运行的内容。我们可以这样计数

    $ lsmod | wc -l67

    要查看系统中可用的模块数(不止运行当中的),试试这个命令:

    $ modprobe -c | wc -l41272

    与内核模块相关的其他命令

    Linux 提供了几条用于罗列、加载及卸载、测试,以及检查模块状态的命令。

    depmod—— 生成modules.dep和映射文件

    insmod—— 一个往 Linux 内核插入模块的程序

    lsmod—— 显示 Linux 内核中模块状态

    modinfo—— 显示 Linux 内核模块信息

    modprobe—— 添加或移除 Linux 内核模块

    rmmod—— 一个从 Linux 内核移除模块的程序

    显示内置的内核模块

    正如前文所说,lsmod 命令是显示内核模块最方便的命令。然而,也有其他方式可以显示它们。modules.builtin 文件中列出了所有构建在内核中的模块,在 modprobe 命令尝试添加文件中的模块时会使用它。注意,以下命令中的$(uname -r)提供了内核版本的名称。

    $ more /lib/modules/$(uname -r)/modules.builtin | head -10kernel/arch/x86/crypto/crc32c-intel.kokernel/arch/x86/events/intel/intel-uncore.kokernel/arch/x86/platform/intel/iosf_mbi.kokernel/mm/zpool.kokernel/mm/zbud.kokernel/mm/zsmalloc.kokernel/fs/binfmt_script.kokernel/fs/mbcache.kokernel/fs/configfs/configfs.kokernel/fs/crypto/fscrypto.ko

    你可以使用 modinfo 获得一个模块的更多细节,虽然没有对模块提供的服务的简单说明。下面输出内容中省略了冗长的签名。

    $ modinfo floppy | head -16filename: /lib/modules/5.0.0-13-generic/kernel/drivers/block/floppy.koalias: block-major-2-*license: GPLauthor: Alain L. Knaffsrcversion: EBEAA26742DF61790588FD9alias: acpi*:PNP0700:*alias: pnp:dPNP0700*depends:retpoline: Yintree: Yname: floppyvermagic: 5.0.0-13-generic SMP mod_unloadsig_id: PKCS#7signer:sig_key:sig_hashalgo: md4

    你可以使用 modprobe 命令加载或卸载模块。使用下面这条命令,你可以找到特定模块关联的内核对象:

    $ find /lib/modules/$(uname -r) -name floppy*/lib/modules/5.0.0-13-generic/kernel/drivers/block/floppy.ko

    如果你想要加载模块,你可以使用这个命令:

    $ sudo modprobe floppy

    总结

    很明显,内核模块的加载和卸载非常重要。它使得 Linux 系统比使用通用内核运行时更加灵活和高效。这同样意味着你可以进行重大更改而无需重启,例如添加硬件。

    展开全文
  • 一、Linux内核模块基本原理Linux 内核模块(LKM)是一些在启动的操作系统内核需要时可以载入内核执行的代码块,不需要时由操作系统卸载。它们扩展了操作系统内核功能却不需要重新编译内核、启动系统。如果没有内核模块...

    一、Linux内核模块基本原理

    Linux 内核模块(LKM)是一些在启动的操作系统内核需要时可以载入内核执行的代码块,不需要时由操作系统卸载。它们扩展了操作系统内核功能却不需要重新编译内核、启动系统。如果没有内核模块,就不得不反复编译生成操作系统的内核镜像来加入新功能,当附加的功能很多时,还会使内核变得臃肿。一个Linux 内核模块主要由以下几个部分组成:

    (1) 模块加载函数(必须):当通过insmod 或modprobe 命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块相关初始化工作。

    (2) 模块卸载函数(必须):当通过rmmod 命令卸载模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能。

    (3) 模块许可证声明(必须):模块许可证(LICENCE)声明描述内核模块的许可权限,如果不声明LICENCE,模块被加载时将收到内核被污染的警告。大多数情况下,内核模块应遵循GPL 兼容许可权。Linux2.6 内核模块最常见的是以MODULE_LICENSE(“Dual BSD/GPL”)语句声明模块采用BSD/GPL 双LICENSE。

    (4) 模块参数(可选):模块参数是模块被加载的时候可以被传递给他的值,它本身对应模块内部的全局变量。

    (5) 模块导出符号(可选):内核模块可以导出符号(symbol,对应于函数或变量),这样其他模块可以使用本模块中的变量或函数。

    (6) 模块作者等信息声明(可选)。

    一个内核模块至少包含两个函数,模块被加载时执行的初始化函数init_module()和模块被卸载时执行的结束函数cleanup_module()。在最新内核稳定版本2.6 中,两个函数可以起任意的名字,通过宏module_init()和module_exit()注册调用要编译内核模块,把代码嵌进内核空间,首先要获取内核源代码,且版本必需与当前正在运行的版本一致。

    二、编写helloworld.c及其对应的Makefile。

    5b504d4698765e12d5a9065ca0fc8a19.png

    在Makefile中,在obj-m := helloworld.o这句中,.o的文件名要与编译的.c文件名一致。 KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r)指示当前linux系统内核的源码位置。

    三、编译:

    1.在Makefile及helloworld.c所在目录下,直接make,成功后查看当前目录下有无helloworld.ko文件产生,有则内核模块生成成功。

    dc4674b5c5ecb038d6b9a6c8ab0c7207.png

    2.使用insmod命令,把此内核模块程序加载到内核中运行。结合lsmod及管道命令,查看内核模块程序在内核中是否正确运行。

    cc3ab006ee572cd887d512e71d5244f9.png

    3.查看此内核模块程序打印的信息,另开一个终端,输入tail -n /var/log/messages. 使用rmmod命令把之前加载的内核模块卸载掉,然后再次执行第2步,即可看到此内核模块程序打印的信息。

    82b2e9cdb7084d3f2573b318c1476856.png

    展开全文
  • 操作系统实践 第12章-添加最简单的Linux内核模块.ppt文档编号:310662文档页数:16上传时间: 2018-07-21文档级别:文档类型:ppt文档大小:2.00MB第12章 添加最简单的Linux内核模块,操作系统实践,山东科技大学操作...

    1cbb08320638fa5f411de9423ba0a513.gif操作系统实践 第12章-添加最简单的Linux内核模块.ppt

    文档编号:310662

    文档页数:16

    上传时间: 2018-07-21

    文档级别:

    文档类型:ppt

    文档大小:2.00MB

    第12章 添加最简单的Linux内核模块,操作系统实践,山东科技大学操作系统教研组,熟练掌握基本的Linux内核模块开发框架和编译方法。 熟练掌握Linux内核模块添加流程。 理解Linux内核模块代码中的一些常见宏和参数。 掌握Linux内核模块程序和应用程序的差异。深入理解操作系统为用户提供服务的方式、方法 深入理解计算机程序的运行方式,本章目标,实验1添加一个简单的Linux内核模块(教材P.162,第12章 添加最简单的Linux内核模块,实验内容 从教材提供的电子资源中找到或者按教材提示自己编写简单的Linux内核模块kello.c及其对应的Makefile文件 编译、安装、删除该模块,查看该模块的安装位置、运行情况,实验1添加一个简单的Linux内核模块,实验要求 通过阅读、执行kello.c及其对应的Makefile文件,理解Linux内核模块LKM的基本框架和运行方式、原理。 对比kello.c和应用程序hello.c在编写、运行过程中的差异,理解操作系统为用户提供服务的方式、方法。 结合操作系统知识,通过实验深入理解计算机程序在操作系统支持下的运行方式。,,实验1添加一个简单的Linux内核模块,原理/背景 用户态和内核态 LKM基本框架、关键代码,,实验1添加一个简单的Linux内核模块,实验1 添加一个简单的Linux内核模块 实验背景和原理,用户态与内核态应用程序调用操作系统服务完成特定功能 操作系统为应用程序提供服务 应用程序工作在用户空间,为用户态 操作系统模块工作在内核空间,为内核态,,C/C应用程序的运行机制,实验1 添加一个简单的Linux内核模块 实验背景和原理,Linux内核模块LKM (Linux Kernel Module) Linux是单内核多模块的操作系统 两种开发内核模块的方法 静态开发 LKMLKM具有如下特点 主要使用C语言编程,但也可以使用内联的汇编代码; LKM工作在内核空间,可以不受约束的运行,因此在一个LKM内部读者可以访问对应用程序屏蔽的内核数据结构、硬件设备等; LKM可以通过proc伪文件系统、内存映射、特定的系统调用函数等不同的机制实现内核空间和用户空间的数据交换。这些机制将在后续章节陆续讲到。,,实验1 添加最简单的Linux内核模块 实验背景和原理,1. LKM代码框架 (教材P. 157),//kello.c include // for printk int kello_init void printk “n Hello, students from SDUST This is in kernel space n“ ;return 0; void kello_exit void printk “n Goodbye now. students from SDUST n“ ; MODULE_AUTHOR“SDUSTOS “; MODULE_LICENSE“GPL“; module_inithello_init; module_exithello_exit;,实验1 添加最简单的Linux内核模块 实验背景和原理,2. LKM代码解释,1)任何一个内核模块文件必须要有两个模块管理函数,即模块初始化函数和模块回收函数,其原型如下所示 int init_module void ; // 模块初始化函数,在模块初始化时被调用 void cleanup_module void ; //模块回收函数,在模块撤销时调用,2)为了模块更高效地被加载、执行和撤销,尤其是内存的分配和回收,在文件最后需要作如下声明 module_initinit_module; //执行模块初始化函数 module_exitcleanup_module; //执行模块回收函数,实验1 添加最简单的Linux内核模块 实验背景和原理,3. LKM编译,第一种是集成到内核、随内核一起编译;这种方法把开发完的内核文件放在Linux内核源代码相关目录下,随内核一起编译。 缺点耗时长;一旦代码有错,导致系统出现问题,第二种则是单独编译、动态插入内核;把将开发的内核代码文件直接进行编译,然后使用命令动态插入内核或者从内核卸载。 优点编译速度快;单独调试代码 缺点每次系统启动后都需要再加载代码,实验1 添加最简单的Linux内核模块 实验背景和原理,3. LKM编译,第二种则是单独编译、动态插入内核;把将开发的内核代码文件直接进行编译,然后使用命令动态插入内核或者从内核卸载。,ifneq KERNELRELEASE, obj-m kello.o else KDIR /lib/modules/shell uname -r/build PWD shell pwd default MAKE -C KDIR SUBDIRSPWD modules rm -r -f .tmp_versions *.mod.c .*. *.o *.symvers endif,Makefile完整代码 教材P.159 内核编译需要Linux内核文件的支持。 /shell uname -r/的作用 编译命令 kello.c和Makefile存储目录下执行make,实验1 添加最简单的Linux内核模块 总结,表12.1 基于C语言的应用程序与内核模块的差异,实验1 添加最简单的Linux内核模块 实验步骤,LKM编译、添加、显示执行结果以及删除模块, sudo rmmod kello.ko (删除模块),编译,插入模块,查看内核日志中的执行结果,拓展实验 printk和某些常见宏,static char * log_level “KERN_EMERG“,“KERN_ALERT“,“KERN_CRIT“,“KERN_ERR“,“KERN_WARNING“,“KERN_NOTICE“,“KERN_INFO“,“KERN_DEBUG“ ;,printk “ Hello, students from SDUST This is in kernel space n“ ;,printk KERN_EMERG “n Hello, students from SDUST This is in kernel space n“ ;,拓展试验教材P162实验2,课后练习,完成本章课后习题与练习中的全部题目,

    展开全文
  • linux内核模块解析

    2021-05-11 21:50:05
    Linux 就是通常所说的单内核(monolithic kernel),即操作系统的大部分功能都被称为内核,并在特权模式下运行。它与微型内核不同,后者只把基本的功能(进程间通信 [IPC]、调度、基本的输入/输出 [I/O]和内存管理)当作...

    Linux 就是通常所说的单内核(monolithic kernel),即操作系统的大部分功能都被称为内核,并在特权模式下运行。它与微型内核 不

    同,后者只把基本的功能(进程间通信 [IPC]、调度、基本的输入/输出 [I/O]

    和内存管理)当作内核运行,而把其他功能(驱动程序、网络堆栈和文件系统)排除在特权空间之外。因此,您可能认为 Linux

    是一个完全静态的内核,但事实恰恰相反。通过 Linux 内核模块(LKM)可以在运行时动态地更改 Linux。

    可动态更改 是指可以将新的功能加载到内核、从内核去除某个功能,甚至添加使用其他 LKM 的新 LKM。LKM 的优点是可以最小化内核的内存占用,只加载需要的元素(这是嵌入式系统的重要特性)。

    Linux 不是可以进行动态更改的惟一(也不是第一个)单内核。Berkeley Software

    Distribution(BSD)的变体、Sun Solaris、更老的内核(比如 OpenVMS),以及其他流行的操作系统(比如

    Microsoft? Windows? 和 Apple Mac OS X)都支持可加载模块。

    LKM,它是以一个什么样的东西呢?我们知道,他编译之后会是一个ko后缀名的东西,但是里面是一个什么样的。我们看,一般的模块的模板。

    /*

    * hello.c  Hello, World! As a Kernel Module

    */

    #include

    #include

    #include

    /*

    * hello_init  the init function, called when the module is loaded.

    * Returns zero if successfully loaded, nonzero otherwise.

    */

    static int hello_init(void)

    {

    printk(KERN_ALERT "I bear a charmed life./n");

    return 0;

    }

    /*

    * hello_exit  the exit function, called when the module is removed.

    */

    static void hello_exit(void)

    {

    printk(KERN_ALERT "Out, out, brief candle!/n");

    }

    module_init(hello_init);

    module_exit(hello_exit);

    MODULE_LICENSE("GPL");

    MODULE_AUTHOR("Shakespeare");

    模块并不是驱动,只是Linux的一种内核扩展机制,驱动就是借助这种机制的,理论上应该这样的理解。

    这就是一个模块的基本模板,通过编译之后,会生成一个ko,注意,编译的时候与其他的应用程序有很大的不同,原因是它生成的东西是一个完全独立的ELF。

    LKM 与直接编译到内核或典型程序的元素有根本区别。典型的程序有一个 main 函数,其中 LKM 包含 entry 和 exit

    函数(在 2.6 版本,您可以任意命名这些函数)。当向内核插入模块时,调用 entry 函数,从内核删除模块时则调用 exit 函数。因为

    entry 和 exit 函数是用户定义的,所以存在 module_init 和 module_exit 宏,用于定义这些函数属于哪种函数。LKM 还包含一组必要的宏和一组可选的宏,用于定义模块的许可证、模块的作者、模块的描述等等。

    2.6 版本的 Linux 内核提供了一个新的更简单的方法,用于构建 LKM。构建 LKM 时,可以使用典型的用户工具管理模块(尽管内部已经改变):标准 insmod(安装 LKM),rmmod (删除 LKM),modprobe(insmod 和 rmmod 的包装器),depmod(用于创建模块依赖项),以及 modinfo(用于为模块宏查找值)。

    LKM 只不过是一个特殊的可执行可链接格式(Executable and Linkable

    Format,ELF)对象文件。通常,必须链接对象文件才能在可执行文件中解析它们的符号和结果。由于必须将 LKM 加载到内核后 LKM

    才能解析符号,所以 LKM 仍然是一个 ELF 对象。您可以在 LKM 上使用标准对象工具(在 2.6 版本中,内核对象带有后缀 .ko,)。例如,如果在 LKM 上使用 objdump 实用工具,您将发现一些熟悉的区段(section),比如 .text(说明)、.data(已初始化数据)和 .bss(块开始符号或未初始化数据)。

    您还可以在模块中找到其他支持动态特性的区段。.init.text 区段包含 module_init 代码,.exit.text 区段包含 module_exit 代码(参见图 2)。.modinfo 区段包含各种表示模块许可证、作者和描述等的宏文本。

    39997452_1.jpg

    在用户空间中,insmod(插入模块)启动模块加载过程。insmod 命令定义需要加载的模块,并调用 init_module 用户空间系统调用,开始加载过程。2.6 版本内核的 insmod 命令经过修改后变得非常简单(70 行代码),可以在内核中执行更多工作。insmod 并不进行所有必要的符号解析(处理 kerneld),它只是通过 init_module 函数将模块二进制文件复制到内核,然后由内核完成剩余的任务。

    init_module 函数通过系统调用层,进入内核到达内核函数 sys_init_module(参见图 3)。这是加载模块的主要函数,它利用许多其他函数完成困难的工作。类似地,rmmod 命令会使 delete_module 执行 system call 调用,而 delete_module 最终会进入内核,并调用 sys_delete_module 将模块从内核删除。

    39997452_2.jpg

    在模块的加载和卸载期间,模块子系统维护了一组简单的状态变量,用于表示模块的操作。加载模块时,状态为 MODULE_STATE_COMING。如果模块已经加载并且可用,状态为 MODULE_STATE_LIVE。此外,卸载模块时,状态为 MODULE_STATE_GOING。

    下面开始剖析一下,这样的一个elf文件是如何加入进内核的:

    现在,我们看看加载模块时的内部函数。当调用内核函数 sys_init_module 时,会开始一个许可检查,查明调用者是否有权执行这个操作(通过 capable 函数完成)。然后,调用 load_module 函数,这个函数负责将模块加载到内核并执行必要的调试(后面还会讨论这点)。load_module 函数返回一个指向最新加载模块的模块引用。这个模块加载到系统内具有双重链接的所有模块的列表上,并且通过 notifier 列表通知正在等待模块状态改变的线程。最后,调用模块的 init() 函数,更新模块状态,表明模块已经加载并且可用。

    /* This is where the real work happens */

    asmlinkage long

    sys_init_module(void __user *umod,

    unsigned long len,

    const char __user *uargs)

    {

    struct module *mod;

    int ret = 0;

    /* Must have permission */

    if (!capable(CAP_SYS_MODULE))

    return -EPERM;

    /* Only one module load at a time, please */

    if (mutex_lock_interruptible(&module_mutex) != 0)

    return -EINTR;

    /* Do all the hard work */

    mod = load_module(umod, len, uargs);

    if (IS_ERR(mod)) {

    mutex_unlock(&module_mutex);

    return PTR_ERR(mod);

    }

    /* Drop lock so they can recurse */

    mutex_unlock(&module_mutex);

    blocking_notifier_call_chain(&module_notify_list,

    MODULE_STATE_COMING, mod);

    /* Start the module */

    if (mod->init != NULL)

    ret = do_one_initcall(mod->init);

    if (ret < 0) {

    /* Init routine failed: abort.  Try to protect us from

    buggy refcounters. */

    mod->state = MODULE_STATE_GOING;

    synchronize_sched();

    module_put(mod);

    blocking_notifier_call_chain(&module_notify_list,

    MODULE_STATE_GOING, mod);

    mutex_lock(&module_mutex);

    free_module(mod);

    mutex_unlock(&module_mutex);

    wake_up(&module_wq);

    return ret;

    }

    if (ret > 0) {

    printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "

    "it should follow 0/-E convention/n"

    KERN_WARNING "%s: loading module anyway.../n",

    __func__, mod->name, ret,

    __func__);

    dump_stack();

    }

    /* Now it's a first class citizen!  Wake up anyone waiting for it. */

    mod->state = MODULE_STATE_LIVE;

    wake_up(&module_wq);

    mutex_lock(&module_mutex);

    /* Drop initial reference. */

    module_put(mod);

    unwind_remove_table(mod->unwind_info, 1);

    module_free(mod, mod->module_init);

    mod->module_init = NULL;

    mod->init_size = 0;

    mod->init_text_size = 0;

    mutex_unlock(&module_mutex);

    return 0;

    }

    加载模块的内部细节是 ELF 模块解析和操作。load_module 函数(位于 ./linux/kernel/module.c)首先分配一块用于容纳整个 ELF 模块的临时内存。然后,通过 copy_from_user 函数将 ELF 模块从用户空间读入到临时内存。作为一个 ELF 对象,这个文件的结构非常独特,易于解析和验证。

    这个函数的代码比较长,实现的就是一个模块的解析,找出各个Section,这个有兴趣的人可以看看Linux内核的源码。

    下一步是对加载的 ELF 映像执行一组健康检查(它是有效的 ELF 文件吗?它适合当前的架构吗?等等)。完成健康检查后,就会解析 ELF

    映像,然后会为每个区段头创建一组方便变量,简化随后的访问。因为 ELF 对象的偏移量是基于 0

    的(除非重新分配),所以这些方便变量将相对偏移量包含到临时内存块中。在创建方便变量的过程中还会验证 ELF 区段头,确保加载的是有效模块。

    任何可选的模块参数都从用户空间加载到另一个已分配的内核内存块(第 4 步),并且更新模块状态,表明模块已加载(MODULE_STATE_COMING)。如果需要 per-CPU 数据(这在检查区段头时确定),那么就分配 per-CPU 块。

    在前面的步骤,模块区段被加载到内核(临时)内存,并且知道哪个区段应该保持,哪个可以删除。步骤 7 为内存中的模块分配最终的位置,并移动必要的区段(ELF 头中的 SHF_ALLOC,

    或在执行期间占用内存的区段)。然后执行另一个分配,大小是模块必要区段所需的大小。迭代临时 ELF

    块中的每个区段,并将需要执行的区段复制到新的块中。接下来要进行一些额外的维护。同时还进行符号解析,可以解析位于内核中的符号(被编译成内核映象),

    或临时的符号(从其他模块导出)。

    然后为每个剩余的区段迭代新的模块并执行重新定位。这个步骤与架构有

    关,因此依赖于为架构(./linux/arch//kernel/module.c)定义的 helper

    函数。最后,刷新指令缓存(因为使用了临时 .text 区段),执行一些额外的维护(释放临时模块内存,设置系统文件),并将模块最终返回到 load_module。

    展开全文
  • Linux内核模块的编程方法(转)[@more@]相信许多朋友和我一样都在Linux环境下使用过C语言编过程序,其大多数都属于用户应用程序,也称为普通用户程序。写了这么多应用程序后,就有点儿想写一点系统级的程序了,于是就...
  • Linux内核模块HelloWorld

    2021-09-16 13:08:02
    内核模块 内核整体架构非常庞大,编译时只把需要的功能编译到内核,其他部分可以编译成模块(.ko文件),在内核运行时,可动态注册模块到内核,也可卸载模块。 本文代码:...
  • Linux 内核模块是一段编译后的二进制代码,直接插入 Linux 内核中,在 Ring 0 (x86–64处理器中执行最低和受保护程度最低的执行环)上运行。这里的代码完全不受检查,但是运行速度很快,可以访问系统中的所有内容。...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼rmmod rtl8139命令将其从系统中卸载出去。...在卸载B模块之前也要首先卸载A模块,否则就会导致系统的崩溃(当然,如果模块源程序编写的正确,在卸载A模块之前,B模块...
  • 一个在X86上的Linux,如果要编写了一个内核模块,我们可以按照下满的Makefile格式来写,然后生成了.ko文件,insmod就可以了原文件是opps.cifneq ($(KERNELRELEASE),)obj-m := opps.oelseKDIR := /lib/modules/2.6.18...
  • Linux内核模块与_proc文件系统2007年第1期福建电脑163Linux内核模块与/proc文件系统文运平,韩秀娟(河南理工大学河南焦作454000)【摘要】:/proc文件系统是一个伪的文件系统,就是说它...
  • Linux内核模块编程

    2021-05-11 11:07:34
    Linux内核模块编程是一个很重要的知识点。尤其是编写底层驱动程序时,一定会涉及到它。内核模块编程也是Tiger哥学习Linux时第一节课所接触的知识。由此可以看出它的important,也可以看出其实它很easy。一前言:1. ...
  • Linux 内核模块是一段编译后的二进制代码,直接插入 Linux 内核中,在Ring 0(x86–64处理器中执行最低和受保护程度最低的执行环)上运行。这里的代码完全不受检查,但是运行速度很快,可以访问系统中的所有内容。 ...
  • linux内核模块加载命令

    千次阅读 2021-01-04 20:25:48
    1、lsmod 列加以挂载的内核模块; lsmod 是列出目前系统中已加载的模块的名称及大小等;另外我们还可以查看 /proc/modules ,我们一样可以知道系统已经加载的模块; [root@localhost beinan]# lsmod 2、modinfo ...
  • linux 内核模块命令

    2021-05-13 15:56:05
    内核模块加载相关的配置文件 模块的配置文件 modules.conf 或 modprobe.conf 内核模块的开机自动挂载模块一般是位于一个配置文件,一般的Linux发行版本都有 /etc/modules.conf 或 /etc/modprobe.conf 。...
  • (1)什么是Linux内核模块首先什么是内核模块呢?这对于初学者无非是个非常难以理解的概念。内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),我们简称为模块。...
  • 一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析。 模块的Hello World! 我们通过创建一个简单的模块进行测试。首先是源文件main.c和Makefile。 florian@florian-pc:~/...
  • 我正在尝试使用vanilla 3.1.0-rc10内核在CentOS 6机器上更新内核.它似乎有效,除了创建的模块的大小明显大于来自发行版RPM的模块.这是一个问题,因为mkinitrd命令最终会创建一个大小为100M的initram文件(因为其中包含...
  • /boot/configure-*为当前Linux内核模块配置文件,即在当前Linux内核中,系统已启用了哪些模块,哪些内容已编译到Linux内核等等,都可以通过此文件来查看。例如,查看当前Linux内核是否支持NTFS文件系统,可使用...
  • 我已经制作了一个新的Linux TCP cong算法实现,并且在这段代码中有一些静态变量,我希望它们通过使用一些配置方法是动态的.根据我在内核级编程中的理解,我们无法加载一些文本文件并将值放在那里并通过程序读取它.但我...
  • Linux 内核模块

    2021-05-17 18:20:14
    1 Linux 内核模块简介Linux 内核是一个十分庞大的系统,如何能够为其瘦身,订制适合自己应用场景的 linux 系统,这就需要了解模块技术。linux 内核与各模块的关系分为两种:把所有需要的功能都直接编译进入内核,但...
  • ldd命令,显示应用程序(二进制程序)所... linux-vdso.so.1 => (0x0000ffff9ea70000) libc.so.6 => /lib64/libc.so.6 (0x0000ffff9e890000) /lib/ld-linux-aarch64.so.1 (0x0000ffff9ea80000) lsmod:显示...
  • linux内核对插入的内核模块进行严格的版本检查,即使一个小版本号不一致也会导致加载的不成功,这完全是为了内核本身运行安全。由于linux内核的发布是基于版本号的,而所有的内核模块的开发必须依赖内核头文件--其...
  • 不幸的是,这意味着我需要在用户空间中保留此功能,因为Linux内核不能很好地处理浮点运算.这是设置的伪表示(请注意,此代码不执行任何特定操作,它只显示我的代码的相对布局):char calculate_output(char x){double y =...
  • 在基本完成了整个初始化过程以后,我们需要再回到网络设备上来,看看整个TCP/IP协议...而在my_inet模块的初始化过程中,mydevinet_init的工作是为MY_PF_INET域的工作找到可用的网络设备,并进行必要的初始化,在myde...
  • 做好了linux内核模块,装载的时候经常遇到 “could not insert module *.ko: Invalid module format”情况,此时通过dmesg查看会报错误信息,“disagrees about version of symbol module_layout”
  • Linux内核模块 前言 操作系统编程项目Linux内核模块 准备工作 1:准备好Linux环境,下载好make和gcc可参考以下教程 gcc安装 make安装 2:Linux下建立Makefile文件 obj-m += simple.o all: make -C /lib/modules/$...
  • 【摘要】本文详解了Linux内核模块的动态加载技术。首先介绍了Linux内核采用LKM的好处,接着介绍了内核模块的基本结构。在分析了动态加载链接技术/ELF格式内核模块组成/内核符号表的基础之上,详细介绍了模块加载卸载...
  • 我仍然不知道为什么高缓存使用导致内核模块到OOM.问题在于我们无法访问的第三方代码,因此谁知道他们在做什么.我想有人可以争辩,如果这是设计,非关键磁盘缓存可以占用所有可用的空闲内存,并导致内核模块到OOM,那么恕...
  • 小编典典我以为您不能在Linux内核中执行浮点运算您不能 放心 :不使用kernel_fpu_begin()/kernel_fpu_end()并不表示FPU指令会出错(至少不是在x86上)。相反,它将以静默方式破坏用户空间的FPU状态。这是不好的; 不要...
  • 用VSCode进行Linux内核模块开发的BUG解决方案 今天想要尝试一下Linux内核编程,按照极客教程博客一步一步进行。但VSCode太不友好了,报了一堆错。 错误长下面这个样子: 不断查找资料,最后修改c_cpp_properties....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 240,825
精华内容 96,330
关键字:

linux内核模块

linux 订阅