linux编译模块,包含了头文件却还是报undifind警告
在编写一个自己写的gadget驱动的时候遇到一个这样的问题,编译的时候报了个警告:WARNING: "usb_composite_register" […/my_zero.ko] undefined!
告诉我这个函数没有定义,但是生成了ko文件,将这个文件拷贝到开发板目录下insmod,同样也是报这是一个未知的符号:
通常这种问题是因为没有包含函数头文件,这个函数是在linux/usb/composite.c中定义的,在composite.h中声明,因此包含linux/usb/composite.h就可以了…吗?事实上我已经包含了这个头文件。
这个时候我想到了光包含头文件不行啊,还要编译源文件啊。不过我似乎发现一个很奇怪的问题,那就是要编译源文件似乎是理所当然的,但问题是之前写驱动调用的那些函数也没有把它们的源文件放进来编译啊。比如说最开始写驱动的时候一定调用过printk,这个函数在printk.c中定义,但也没见哪条语句指定要把printk.c拿进来编译啊。
查找资料过后发现原来是EXPORT_SYMBOL搞的鬼,就是说使用EXPORT_SYMBOL导出的函数可以被其他内核模块使用,那这是不是说,把usb_composite_register这个函数用EXPORT_SYMBOL导出就可以了呢。我们在内核代码中usb_composite_register这个函数后面用EXPORT_SYMBOL将其导出,然后编译自己的模块,发现还是报相同的警告。难道要重新编译一下内核吗,于是我重新编译了内核,编译内核时它警告我usb_composite_register这个函数在g_serial.o中已经被导出了,但这是一个警告,我想问题应该不大。接下来再编译自己的模块,它就不报警告了。
既然和重新编译内核有关,那自然也要下载新编译的内核了,将新的内核下载进开发板后再insmod我编译的ko文件,结果还是报Unknown symbol usb_composite_register。
再查过资料后发现还有一个关键点我没做到,那就是必须先insmod包含要导出的函数的模块,然鹅查找了composite.c这个文件后发现这个文件里没有module_init,就意味着这不是一个独立的模块,也就没法“先insmod包含要导出的函数的模块”。
连源文件都给了,难道还调不了函数了吗,这怎么可能。我们可以看看内核文件里其他模块都是怎么做的,找到其他的gadget驱动文件,发现他们都比较流弊,是直接#include “composite.c”,直接把c文件包含进来了。这里可能有些朋友比较蒙圈(“只见过包含.h,没见过包含.c啊”),其实只要清楚#include的机制就能理解了。#include的作用是将包含的文件在使用#include处展开,不管是包含.c还是包含.h,都是将被包含的文件里的内容在包含处展开,相当于把被包含的文件里的内容全部复制下来,在#include处粘贴一样。
既然这样,那我也包含composite.c这个文件试试,先将composite.c复制到我自己的驱动目录下,结果一编译又报出几个警告:
那自然的要把包含这些函数的.c文件拿过来编译。发现这几个函数分别是在epautoconf.c、config.c和usbstring.c中定义的,把这些文件拷贝到自己的工作目录下,同时在c文件中包含它们,再编译又报一个找不到gadget_chips.h的错,把这个文件再拷贝到工作目录中,再编译。
最后将生成的ko文件拷贝到开发板工作目录中,再insmod就可以了。
如果嫌把这些文件都拷贝过来太麻烦的话,可以直接在内核代码目录下加入自己的模块,参见:https://www.cnblogs.com/Suzkfly/p/11765883.html
linux编译模块,包含了头文件却还是报undifind警告的更多相关文章
- linux 编译指定库、头文件的路径问题(转)
1. 为什么会出现undefined reference to 'xxxxx'错误? 首先这是链接错误,不是编译错误,也就是说如果只有这个错误,说明你的程序源码本身没有问题,是你用编译器编译时参数用得 ...
- Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50
Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50 分类: 系统运维 查找包含BOM头的文件,命令如下: 点击(此处)折叠或打开 grep -r -I -l ...
- C预编译, 预处理, C/C++头文件, 编译控制,
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...
- 编写linux驱动所用到的头文件(转)
转自:http://blog.csdn.net/lufeiop02/article/details/6448497 关于linux驱动(应用)程序头文件使用 收藏 驱动程序: #include < ...
- linux 中常用的一些头文件
#include <linux/***.h> 是在linux-2.6.29/include/linux下面寻找源文件. #include <asm/***.h> 是在linux ...
- gcc/clang编译带pthread.h头文件的源码时需要的参数
今天敲了一个小程序,编译时出现错误:undefined reference pthread_create 原来由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a, ...
- [C++] C语言及C++语言中包含的头文件名称,及作用
头文件主目录include 头文件目录中总共有32个.h头文件.其中主目录下有13个,asm子目录中有4个,linux子目录中有10个,sys子目录中有5个.这些头文件各自的功能如下,具体的作用和所包 ...
- cocos2dx中使用声音引擎需要包含的头文件
1.需要包含的头文件和命名空间 #include "SimpleAudioEngine.h"using namespace CocosDenshion;
- 不包含SDK头文件, 补全API定义
/// @file main.cpp /// @brief 不包含SDK头文件, 补全API定义 #ifdef __cplusplus extern "C" { #endif /* ...
随机推荐
- Laravel笔记记录
1.获取当前控制器和action名称 request()->route()->getAction()
- 【对线面试官】Java注解
public void send(String userName) { try { // qps 上报 qps(params); long startTime = System.c ...
- SQL语句中case,when,then的用法
用法如下bai: 复制代码 SELECT s.s_id, s.s_name, s.s_sex, CASE WHENs.s_sex='1'THEN'男' WHENs.s_sex='2'THEN'女' E ...
- Node.js躬行记(5)——定时任务的调试
最近做一个活动,需要用到定时任务,于是使用了 node-schedule 库. 用法很简单,就是可配置开始.结束时间,以及重复执行的时间点,如下所示,从2020-12-23T09:00:00Z开始,每 ...
- [leetcode]449. Serialize and Deserialize BST设计BST的编解码
这道题学到了东西. /* 一开始想着中序遍历,但是解码的时候才发现,中序遍历并不能唯一得确定二叉树. 后来看了网上的答案,发现先序遍历是可以的,观察了一下,对于BST,先序遍历确实是可以 唯一得确定. ...
- ProxyDroid+wifi设置抓xx点评抓不到的包
ProxyDroid+wifi设置抓xx点评抓不到的包 一.ProxyDroid介绍 1.下载地址 下载并安装ProxyDroid.(确保您的设备已经ROOT)点击下载 2.界面介绍 (1) Auto ...
- javaweb登陆实例
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncod ...
- vue中Echarts的使用-自选效果
由于项目要求使用数据图,于是我选择了我们的Echarts用来实现效果 一:全局安装Echarts npm install echarts --save(这个安装的是最新的版本有时候回报init未定义) ...
- JAVA_基础IO流随机存取文件流(四)
随机存取文件流 RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类.并 且它实现了DataInput.DataOutput这两个接口,也就意味着 ...
- 我的开源项目在五个月内超过了 600 star
其实我在 2016 年年底就开始写了这个项目:Forest,一个能够将 HTTP 的所有请求信息(包括 URL .Header 以及 Body 等信息)绑定到您自定义的 Interface 方法上,能 ...