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

电子说

1.2w人已加入

描述

更多技术干货内容请稳步到“电子发烧友网”公众号,回复资料即可免费获取一份技术资料,在这里每天可以获取最专业、最前沿的电子技术。
Linux内核是整体性结构,各个子系统紧密联系,上接用户控件,下接硬件,作为一个大程序在内核控件运行。

如果将所有的设备驱动和内核功能都集成在内核中,则内核会不断的庞大,对我们的内核裁剪也会带来更大的挑战,为了解决这个问题,Linux内核引入内核模块机制,通过动态加载内核模块,从而实现在运行过程中扩展内核的功能。

L

内核模块是什么?

1 内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间中运行的程序。经过链接装载到内核里面成为内核的一部分,可以访问内核的公用符号(函数和变量)。

2 内核模块可以让操作系统内核在需要时载入和执行,在不需要时由操作系统卸载。它们扩展了操作系统内核的功能却不需要重新启动系统。

3 如果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜像来加入新的功能。这还意味着一个臃肿的内核。

模块机制的优点:

1 减小内核映像尺寸,增加系统灵活性;

2 节省开发时间;修改内核,不必重新编译整个内核。

3 模块的目标代码一旦被链入内核,作用和静态链接的内核目标代码完全等价。

模块机制的缺点:

1 对系统性能有一定损失;

2 使用不当时会导致系统崩溃;

接下来通过介绍一下内核模块的实现:

首先先附上模块的代码(hello_world.c

 1 #include

 2 #include

 3 #include

 4

 5 static int hello_init(void)

 6 {

 7         printk("hello world module! ");

 8         return 0;

 9 }

10

11 static void hello_exit(void)

12 {

13         printk("good bye module! ");

14 }

15

16 module_init(hello_init);

17 module_exit(hello_exit);

18

19 MODULE_LICENSE("GPL");

内核模块至少包含两个函数:

入口函数->初始化函数(xxx_init()):模块加载时,被调用

出口函数->卸载函数(xxx_exit()):模块卸载时,被调用

模块的入口函数名和出口函数名可以任意命名,通过宏module_init()申明入口函数,通过宏module_exit()申明出口函数。模块需要包含头文件:#include

内核模块证书:2.4内核后,引入识别代码是否在GPL许可下发布的机制 。在使用非公开的源代码产品时会得到警告。通过宏MODULE_LICENSE(“GPL”),设置模块遵守GPL证书,取消警告信息。

内核模块的构建:

管理模块源码方法: ① 模块源码加入到内核源码树中。② 模块源码饭仔内核源码树之外。

注:本文介绍的是放在内核源码树外编译。

接下来是Makefile的实现:

首先附上Makefile的源码

 1 KERNEL_DIR = /home/FAN/linux-kernel

 2

 3 all:

 4         make -C $(KERNEL_DIR) M=`pwd` modules

 5 clean:

 6         make -C $(KERNEL_DIR) M=`pwd` modules clean

 7         rm -rf modules.order Module.symvers

 8

 9 obj-m += hello_world.o

其中:

1、KERNEL_DIR:参数,赋值内核的位置,例如我的内核源码的路径:/home/fan/linux-kernrl

2、当终端执行make时,会运行make -C $(KERNEL_DIR) M=`pwd` modules,其中M=`pwd`指向是模块所在的路径。

3、当终端执行make clean时,会运行下面两条命令,将编译生成的文件删除

make -C $(KERNEL_DIR) M=`pwd` modules clean

  rm -rf modules.order Module.symvers

4、obj-m += hello_world.o:其中 –m 表示将hello_world.c编译成模块

                             –y 表示将hello_world.c编译进内核镜像中

编译生成文件:

在终端运行make,则会生成hello_world.ko文件.

L

hello_world.ko发送到板子上,然后在板子上运行insmod  hello_world.ko, 会调用hello_init()函数运行rmmod hello_world.ko,会调用hello_exit()函数

下图为运行结果:

L

本文作者:饭仔DIY,工作之余喜欢电子DIY,开源分享是我写文章的动力,互相学习才能让自己不断强大。

欢迎广大电子发烧友们投稿,投稿邮箱:liuyong@elecfans.com


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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分