Kernel中Module调用编译问题

   最近在kernel driver中写一个功能,遇到module之间调用的问题,以此记录一下。

在kernel中两个不同的模块之间是不能通过简单的#include “XX.h”来相互调用函数的。如果这样在调用的地方不会出现语法错误,但是在最后生成模块文件XXX.ko时就会出现error:“xxxx” 【xxx.ko】undefined! 在生成 .ko文件(kernel object)这个时候就报资源没有定义的错误了。

出现这样的情况是因为kernel的模块都是相互独立的,如果要共享就必须做一些处理了。


以/driver中的gpio和ir这两个module为例,如下:

ir.c中调用gpio中对gpio口操作的函数:

void MDrv_GPIO_Set_High(U8 u8IndexGPIO);


一.被调用模块gpio


1.gpio.c中被调用函数必须添加EXPORT_SYMBOL声明,如下:

void MDrv_GPIO_Set_High(U8 u8IndexGPIO)
{
    MHal_GPIO_Set_High(u8IndexGPIO);
}
EXPORT_SYMBOL(MDrv_GPIO_Set_High);

EXPORT_SYMBOL声明一下函数是为了奖此函数导出,可供外部使用!


2.gpio模块中的Kconfig以及Makefile设置

Kconfig中必须定义Kernel中相对应的模块名:

config MDRV_GPIO

Makefile中编译目标:

obj-$(CONFIG_MDRV_GPIO)	+= gpio.o

3.被调用模块上层的Makefile配置

gpio.c的上一目录driver中的Makefile中:

obj-$(CONFIG_MDRV_GPIO)                            += gpio/

其中gpio也就是gpio.c所在的目录。


这样MDrv_GPIO_Set_High才能被正确的导出到kernel的根目录下的Module.symvers文件,这个文件里面就是kernel里所有的EXPORT_SYMBOL和EXPORT_SYMBOL_GPL导出来的符号以及函数,EXPORT_SYMBOL_GPL和EXPORT_SYMBOL的区别就是:如果module的协议不是GPL的, 那么EXPORT_SYMBOL_GPL导出的那些符号以及函数,就用不了!

这个Module.symvers每次编译kernel的时候重新生成!

如果碰到上面的编译错误,第一步就是到这个Module.symvers中查看是否有你要调用的函数或者变量!


二.调用模块ir

在ir.c中需要调用MDrv_GPIO_Set_High(U8 u8IndexGPIO):

extern void MDrv_GPIO_Set_High(U8 u8IndexGPIO);




这样ir.c中的函数就可以调用 MDrv_GPIO_Set_High(U8 u8IndexGPIO)这个函数啦!


撰写不易,转载请注明出处http://blog.csdn.net/jscese/article/details/16991679




### 回答1: 您好! 在 Android ,内核模块是可以动态加载到内核的一段代码,它可以为内核提供新的功能或者修改内核的已有功能。 要在 Android 创建内核模块,您需要先确保已安装了内核源代码和所需的开发工具(例如 GCC 编译器)。接下来,您可以使用内核源代码提供的模板文件创建一个新的内核模块。您还需要编写代码来实现您想要模块完成的任务。最后,您可以使用 make 命令编译模块并使用 insmod 命令将其加载到内核。 关于内核版本 5.15,这是一个 Linux 内核版本,用于维护内核代码并提供新功能。在 Android 使用的内核版本可能与此版本不同,因此您需要确保正在使用适用于您的设备的内核版本。 希望这能帮到您! ### 回答2: helloworld android kernel module 5.15 是指一个在 Android系统运行的内核模块示例程序,版本为5.15。内核模块是一种可以加载和卸载的软件,它可以扩展内核的功能并与操作系统交互。 "Hello World"是一个常见的示例程序,用于展示某个编程环境或语言的基本使用方法。在这个内核模块,"Hello World"表示这个模块的功能是简单地在 Android内核打印输出 "Hello World"这个信息。这个模块可能是一个简单的示例,用于演示如何创建和加载内核模块,并在内核执行一些基本的操作。 Android是一个基于 Linux的操作系统,它在移动设备和嵌入式系统广泛使用。Android系统的内核是基于 Linux内核的,因此可以使用内核模块来扩展其功能。内核模块可以访问底层硬件、增加新的系统调用、修改内核配置等。它可以通过编译成二进制文件,并通过 insmod命令加载到 Android 系统。 版本号"5.15"表示这个内核模块的版本号,可能是指所使用的 Linux内核版本为5.15。版本号通常用于标识软件的不同发布版本,每个版本可能包含不同的功能和修复不同的 bug。 总之,helloworld android kernel module 5.15 是一个简单的 Android 系统内核模块示例程序,用于展示如何在 Android系统创建并加载内核模块,并打印输出 "Hello World"。版本号5.15可能指该示例程序所运行的 Linux内核版本。 ### 回答3: helloworld是一个常用于程式设计初学者学习的例程,它的作用是在屏幕上打印出"Hello, World!"这个简单的字符串。在Android系统,我们可以创建一个基于helloworld的kernel module,在Android的内核加载此模块,从而在系统启动时执行该模块的代码。 Android内核模块是一种扩展内核功能的方式,可以添加自定义的驱动程序或系统功能。在5.15版本的Android内核,我们可以开发和加载一个基于helloworld的内核模块。 创建一个helloworld的Android内核模块需要以下步骤: 首先,我们需要在Android源代码kernel目录下创建一个新的模块目录,并确认Makefile文件添加了该模块的路径。 然后,在模块目录下创建一个.c源文件,我们可以将其命名为helloworld.c,其包含了在加载内核模块时执行的代码,例如打印"Hello, World!"。 在代码,我们需要包含头文件和内核模块相关的函数,并实现一个init函数和一个exit函数。init函数在模块加载时执行,而exit函数在模块卸载时执行。 在完成代码编写后,我们需要修改模块的Makefile文件,添加模块的编译选项和模块的名称。 最后,编译整个Android系统并将模块导入到Android手机上。 在Android系统启动时,内核会加载helloworld模块,并执行其的代码。这样,我们就能在系统启动时在屏幕上看到"Hello, World!"这个字符串。 总结起来,helloworld android kernel module 5.15是一种在Android 5.15内核创建和加载helloworld内核模块的方法。通过编写相应的代码并进行编译,我们可以在系统启动时看到"Hello, World!"字符串的输出。这是一个简单的例子,可以帮助初学者理解Android内核模块的创建和加载过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值