Linux内核模块编程入门( 最简单的内核模块编程)

您所在的位置:网站首页 最简linux Linux内核模块编程入门( 最简单的内核模块编程)

Linux内核模块编程入门( 最简单的内核模块编程)

2024-04-08 15:17| 来源: 网络整理| 查看: 265

第1章简介 什么是内核模块?

所以,你想编写一个内核模块。 你知道C,你已经编写了一些正常的程序作为进程运行,现在你想要到达实际操作的位置,一个狂野指针可以消灭你的文件系统,核心转储意味着重启。

什么是内核模块? 模块是可以根据需要加载和卸载到内核中的代码片段。 它们扩展了内核的功能,而无需重启系统。 例如,一种类型的模块是设备驱动程序,它允许内核访问连接到系统的硬件。 没有模块,我们必须构建单片内核并将新功能直接添加到内核映像中。 除了拥有更大的内核之外,这还有一个缺点,即每次我们想要新功能时都需要我们重建和重启内核。

模块如何进入内核?

您可以通过运行lsmod来查看已经加载到内核中的模块, lsmod通过读取文件/proc/modules来获取其信息。

这些模块如何进入内核? 当内核需要一个不驻留在内核中的特性时,内核模块守护进程kmod [1]执行modprobe来加载模块.modprobe以两种形式之一传递一个字符串:

linux系统整体结构分三个部分 

linux内核模块编程入门()

这里的printk就是print kernal,意思是输出到内核,输出到日志文件

当模块插入执行初始化lkp__init()函数

当模块卸载执行退出函数lkp__exit()

//任何模块都要包含的三个头文件 #include //(module模块; 功能块)包含了对模块的版本控制 #include //包含了常用的内核函数 #include //包含了宏__init(告诉编译程序仅初始化的函数和变量)和__exit() /*     模块的初始化函数lkp_init()     __init是用于初始化的修饰符 */ static int __init lkp_init(void) //加载函数的入口函数 相当于 main(void) {     printk("Hello,world!from the kernel space...\n");//Linux内核下内核编程不能使用c的库 } /*     模块的退出和清理函数lkp_exit() //入口相对的出口 */ static void __exit lkp(void) {     printk("Goodbye,world!leaving kernel space...\n"); } /*     调用函数 */ module_init(lkp_init); module_exit(lkp_exit); /*     模块的许可证声明GPL */ MODULE_LICENSE("GPL");

 

内核模块的Makefile文件

编译内核模块

内核模块的编译需要与常规用户空间应用程序略有不同。 以前的内核版本要求我们关注这些设置,这些设置通常存储在Makefile中。 虽然按层次结构组织,但许多冗余设置在次级Makefile中累积并使它们变大并且难以维护。 幸运的是,有一种新方法可以做这些事情,称为kbuild,外部可加载模块的构建过程现在完全集成到标准内核构建机制中。 要了解有关如何编译不属于官方内核的模块的更多信息(例如本指南中的所有示例),请参阅文件linux / Documentation / kbuild / modules.txt 。

那么,让我们看一个简单的Makefile来编译一个名为hello-1.c的模块:

obj-m += hello-1.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

核心思想:告诉哪个头文件放在哪些地方

在这个文件里定义了三个变量 

1. 路径的变量

2.内核版本号变量

 3.内核源代码所在路径变量

内核模块插入到内核里

 超级用户的权限插入

#insmod + 模块名.ko

 

 

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3