Linux模块编程

本文详细介绍了Linux内核模块编程的相关知识,包括模块的学习内容、内核模块概述、模块的认识、模块的安装、卸载和查看命令,以及模块的基本程序框架。文章通过实例演示了如何编译、安装和卸载模块,强调了模块版本与内核版本的一致性要求,并探讨了模块间的依赖关系。同时,文章还讲解了模块传递参数的概念,包括支持的数据类型和权限类型。
摘要由CSDN通过智能技术生成

Linux模块编程

1.1 模块学习什么

1.认识什么是模块?跟我学习的驱动有什么关系?

2.熟悉模块的安装,卸载,查看

3.熟悉模块的基本框架

4.熟悉模块的编程方法

1.2 内核模块概述

Linux 内核的整体结构非常庞大,其包含的组件也非常多。我们怎样把需要的部分都包含在内核中呢?一种方法是把所有需要的功能都编译到 Linux 内核。这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核。

有没有一种机制使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码可被动态地加载到内核中呢?

Linux 提供了这样的一种机制,这种机制被称为模块(Module,可以实现以上效果。模块具有以下特点。

1.模块本身不被编译入内核映像,从而控制了内核的大小。

2.模块一旦被加载,它就和内核中的其他部分完全一样。

1.3 认识模块

我们在配置内核的时候,在配置菜单看到有一种选项可以选择为<M> <*> < > 。

其中,<M>表示编译成模块,即modules,这个便于选项编译的代码不编译进内核zImage,而是编译成一个单独的文件,通常为后缀.ko(2.6以上内核版本是.ko,2.6内核之前是.o)文件,那么我们可以像软件一样选择安装和卸载这些.ko模块文件。

<*>表示编译进内核,就是将这一段模块代码编译到了zImage镜像文件去了,在内核启动的时候自动安装执行我们的模块代码,这样做类似于一些安装系统的时候自带的驱动,在安装系统的时候就已经安装好了。

< > 表示没有选择,不做任何事情。

所以,我们所说的模块就是linux下的那些.ko文件

1.3.1 tiny4412提供的模块测试程序

在我们学习的Tiny4412提供的 Linux3.5 源码中有一项模块测试选项,如下:

         Tiny4412module sample.

         Symbol:TINY4412_HELLO_MODULE [=m]

         Type: tristate

         Prompt:Tiny4412 module sample

         Definedat drivers/char/Kconfig:49

         Dependson: ARCH_EXYNOS4 [=y]

Location:

          -> DeviceDrivers

                   ->Character devices      

注意:因为有依赖项,所以它的依赖必须被选上,即ARCH_EXYNOS4 [=y]

 CONFIG_ARCH_EXYNOS4:                                                                                

 Samsung EXYNOS4 SoCs based systems                                                                   

 Symbol: ARCH_EXYNOS4[=y]                            

 Type  :boolean                                      

 Prompt: SAMSUNGEXYNOS4                              

  Defined at arch/arm/mach-exynos/Kconfig:14         

  Depends on: ARCH_EXYNOS [=y]                       

  Location:                                          

     -> SystemType                                    

       -> SAMSUNGEXYNOS SoCs Support                 

  Selects: HAVE_SMP [=y] && MIGHT_HAVE_CACHE_L2X0 [=y]

这个测试文件在drivers/char/目录下的tiny4412_hello_moduls.c当把它选择为<M>之后,编译就会在同级目录下生成.ko文件。

编译命令:make modules

在 Linux 系统中,几乎所有驱动都可以编译模块的形式。

总之,模块代码我们可以在系统启动后再安装(zImage文件中并不包含该选项对应的C代码)。也可以编译到内核,像内核配置菜单中选择为y的选项,对应的C代码会被编译到zImage文件中。

这里记住一句话:linux下模块不一定是驱动,但是驱动肯是一种模块

 

示例:编译成模块

1)在linux内核内核配置菜单makememuconfig上把模块测试选项为M,然后退出保存。

2)编译成模块,如下:

[root@localhost linux-3.5]# make modules

scripts/kconfig/conf--silentoldconfig Kconfig

 CHK     include/linux/version.h

 CHK    include/generated/utsrelease.h

make[1]: “include/generated/mach-types.h”是最新的。

 CALL    scripts/checksyscalls.sh

 CC [M]  crypto/ansi_cprng.o

 CC [M] drivers/char/tiny4412_hello_module.o

 CC [M] drivers/scsi/scsi_wait_scan.o

 Building modules, stage 2.

 MODPOST 3 modules

 CC      crypto/ansi_cprng.mod.o

 LD [M]  crypto/ansi_cprng.ko

 CC     drivers/char/tiny4412_hello_module.mod.o

 LD [M] drivers/char/tiny4412_hello_module.ko

 CC     drivers/scsi/scsi_wait_scan.mod.o

 LD [M] drivers/scsi/scsi_wait_scan.ko

[root@localhost linux-3.5]#

以上就会在drivers/char/生成了tiny4412_hello_module.ko文件。

然后我们可以查看一下它的存在:

[root@localhost linux-3.5]# cd drivers/char/

[root@localhost char]# ls tiny4412_hello_module.ko -l

-rw-r--r--. 1root root 29062 9 25 11:26 tiny4412_hello_module.ko

[root@localhost char]#

 

有了.ko文件,那么我们可在以外部独立的来加载到内核,怎么加载呢?又怎么卸载呢?

Linux系统提供专业的命令来完成这样的事情,下面来介绍这几个命令。

1.3.2 Linux模块安装,卸载,查看

Linux下模块提供有安装,卸载,查看安装了那个模块以及查看模块信息等命令。

1.3.1、模块相关命令

insmod <file name.ko>

安装模块进内核

rmmod <file name>

卸载指定的模块

lsmod

查看当前系统安装了哪些模块

modinfo <file name>

查看模块信息

1.insmod   -- 安装模块

示例

[root@JUNJIA /home]# insmod tiny4412_hello_module.ko

[ 140.030000] Hello, Tiny4412 module is installed !

[root@JUNJIA /home]#

2.lsmod    -- 列出当前系统已经安装的模块及模块间的依赖关系(不包含被编译的内核的模块代码)

示例

[root@JUNJIA /home]# lsmod

tiny4412_hello_module 773 0 - Live 0xbf000000

第1列:模块名

第2列:模块大小

第3列:被引用多少次(本模块的代码被多少个模块调用)

第4列:被哪个模块引用

说明

lsmod 命令实际上读取并分析/proc/modules文件。

 

 

在安装模块的时候我们可能会遇到这样的问题,模块版本和要装的linux内核版本不同会出现问题。

比如我修改了编译模块的内核版本号,然后编译查看模块信息:

         [root@localhostlinux-3.5]# modinfo drivers/char/tiny4412_hello_module.ko

         filename:       drivers/char/tiny4412_hello_module.ko

         license:        GPL

         depends:       

         intree:         Y

         vermagic:       3.5.0-FriendlyARM_JUNJIASMP preempt mod_unload ARMv7 p2v8

         [root@localhostlinux-3.5]#

安装会出现以下问题:

         [root@JUNJIA/home]# insmod tiny4412_hello_module.ko

         [3212.730000] tiny4412_hello_module: version magic '3.5.0-FriendlyARM_JUNJIASMP preempt mod_unload ARMv7 p2v8 ' should be '3.5.0-FriendlyARMSMP preempt mod_unload ARMv7 p2v8 '

         insmod:can't insert 'tiny4412_hello_module.ko': invalid module format

         [root@JUNJIA/home]#

这个错误是说模块 版本号是3.5.0-FriendlyARM_JUNJIA,而内核版本号是3.5.0-FriendlyARM,不匹配不能进行加载。那么我就只能

结论:模块版本和内核版本不同是不能安装模块的。

 

3.rmmod    -- 卸载模块(编译在内核的模块代码不可以移除)

示例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值