Linux中多个.c文件编译为一个模块.ko

Makefile独立编译ko文件 在工作的过程中,经常需要编译一些Ko模块,如果是单个的c文件编译直接在内核源码里面 obj-m=xxx.o就好 如果这个ko文件需要多个c文件共同编译生成的话,最好以如下的模板来完成编译较好 #首先指定好编译链工具 CROSS_COMPILE=/opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- #指定用哪个内核去编译 KDIR=/mnt/nfsroot/zhengshuai.zhu/IPCSDK/ipc- 阅读详情

例如现在有三个文件:

exp.c

exps.c

exp.h

这是目前做实验的代码,其中exps中是工具函数,其内容被exp.c调用,exp.h是exps.c文件中函数的声明以及一些结构体的定义。

下面介绍将exp.c与exps.c编译为一个模块ex.ko,以及在这个过程中遇到的一系列问题。

由于exps.c中是一些工具函数,所以在exps.c中不需要module_init、module_exit等来进行修饰,而exp.c要调用exps.c,并且里面含有模块的入口函数和出口函数,所以在exp.c中使用module_init、module_exit等模块结构。

一个模块只有一个入口和出口,所以只有一对module_init、module_exit,同时要添加上MODULE_LICENSE("GPL")。

实验代码不方便贴出来,但是方法已经过真机测试,现在在我的虚拟机上随便写几个函数来演示一下:

exp.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "exp.h"

extern void exps_init(int e);

static int table_init(void)
{
	printk("TABLE: table init \n");
	exps_init(50);   
	return 0;
}

static void table_exit(void)
{
	printk("TABLE: table exit \n");
}

module_init(table_init);
module_exit(table_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me");
MODULE_DESCRIPTION("module test");

extern导入符号是必要的,测试了如果不导入符号,会报如下错误:

error: implicit declaration of function ‘exps_init’ [-Werror=implicit-function-declaration]

即使这句extern 写在exp.h中也不行。

exps.c:

#include "exp.h"
#include <linux/kernel.h>

void print(int e)
{
	printk("parameter is %d \n",e);
}

void exps_init(int e)
{
	printk("hello, this is exps \n");
	print(e);	
}

在exps.c中,符号exps_init会被exp.c调用,这里既可以使用EXPORT_SYMBOL来导出这个符号,也可以不使用EXPORT_SYMBOL,测试了都没有问题。

exp.h:

#ifndef _LINUX_EXP_COMMON_H_
#define _LINUX_EXP_COMMON_H_

void exps_int(int e);

#endif

Makefile:

ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=exp.o exps.o
else
 
#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build

#complie object
default:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif

Makefile是关键,首先 obj-m指定模块名,然后再根据模块名-objs:=依赖的文件。

最开始我想将模块名设置为exp,但是和我的文件重名了,这时候编译虽然成功了,但是插入模块会报如下错误:

[ 2045.410335] exp: module license 'unspecified' taints kernel.
[ 2045.410338] Disabling lock debugging due to kernel taint

所以我不能选择exp或者exps作为模块名~

依赖文件不需要顺序,比如既可以是:

ex-objs:=exp.o exps.o

也可以是:

ex-objs:=exps.o exp.o

使用make编译得到如下内容:

insmod 插入模块后,dmesg就可以得到想要的信息:

 

多个文件:

多个文件也是一样,比如这里我再增加了一个expss.c文件,该文件中函数expss_init被exps.c中函数调用:

此时exps.c:

#include "exp.h"
#include <linux/kernel.h>

extern int expss_init(int e);

void print(int e)
{
	printk("parameter is %d \n",e);
}

void exps_init(int e)
{
	printk("hello, this is exps \n");
	e = expss_init(e);
	print(e);	
}

expss.c:

#include <linux/kernel.h>
#include "exp.h"

int expss_init(int e)
{
	return (e+10);
}

Makefile:

ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=expss.o exps.o exp.o 
else
 
#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build

#complie object
default:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif

编译出文件如下:

插入模块运行如下:

3. 内核模块的Makefile 1.  内核模块的Makefile若要编译hello的内核模块,最简单的方法就是要编写如下内容的Makefile(若对Makefile比较陌生,请参考Linux开发基础讲义):-----------------------------------------------------------------------ifeq ($(KERNELRELEASE),)KERNELDIR 阅读详情

相关推荐

三、Linux内核模块编写(一个c文件生成一个ko文件)

Linux模块编写

qq_1033275663的博客 3689

编译.ko的简单Makefile实例

需要在kernel层编译好的.ko文件,然后放到Android文件系统中进行编译,上层会在适当的时候调用。 需要准备源文件: 我这里systest.c 需要自己编写一个makefile 然后执行make就可以编出systest.ko文件 obj-m := systest.o                                                          

lcqlw123的专栏 3361

Linux模块文件编译到内核与独立编译成.ko文件的方法

很多粉丝在群里提问,如何把一个模块文件编译到内核中或者独立变异成ko文件。本文给大家详解讲解。

嵌入式技术开发 6312

linux .ko的编译与测试

以【tiny210 按键实验为例】 【采用按键驱动(异步通知机制)】 准备: 内核:Linux-3.0.8 (开发板的运行内核) 平台:Fedora14 例子: 建立空文件夹(ko文件),在里面添加需要制成的文件: 内核源码:my_button.c Makefile文件:Makefile 测试文件:buttons_test.c

H_Xjun的博客 2535

Linux将多个C源文件编译进一个KO模块驱动示例

Linux将多个C源文件编译进一个KO模块驱动示例 博文:https://blog.csdn.net/p1279030826/article/details/108040129

从零打造M328晶体管测试仪:硬件DIY与烧录避坑指南

本文是一份详尽的M328晶体管测试仪DIY指南,涵盖从硬件选型、PCB设计、焊接组装到固件烧录的全过程。重点解析了使用AVR单片机与Arduino IDE环境时,如何正确设置熔丝位以避免“白屏”等常见问题,并提供了使用ISP编程器进行烧录的实操步骤与校准方法,帮助电子爱好者成功打造属于自己的高性价比元件测试工具。

weixin_29243063的博客 475

多个.c文件编译成.ko文件

以两个C文件为例: 将本该被分别编译成adc_device.ko和adc_driver.ko的adc_device.c、adc_driver.c编译成一个ko文件! 采用方法: 第一步、修改C文件 1、去掉adc_device.c文件里module_init(xxx)、module_exit(yyy)中xxx、yyy 函数原型的关键字static 2、注销adc_device.c文件里module...

weixin_37867857的博客 6100

记一次在JAVA中客户端使用axis调用webservice服务端出现的异常:Unmarshalling Error: For input string: ""

在使axis调用webservice服务端,参照网上给的demo: Call call = (Call) service.createCall(); call.setTargetEndpointAddress(endpoint);//设置服务请求路径 QName qn = new QName(name); call.setOperationName(qn); call.addParamet

kry1201的专栏 8081

【Linux驱动开发】将多个C源文件编译进一个KO模块

Maindev 是主文件,External 是外部调用文件,将Maindev.c ,External.c,External.h 编译成alex.ko 模块。 在Maindev 里实现入口和出口。 程序编写: Maindev.c #include <linux/init.h> #include <linux/module.h> #include "External.h" static int __init dev_init(void) { p...

丨晋丨 1679

基于STM32的RS485土壤氮磷钾与PH传感器数据采集与OLED显示实战(附完整代码)

本文详细介绍了基于STM32单片机通过RS485协议采集土壤氮磷钾与PH传感器数据的实战项目。涵盖硬件选型、连接方法、Modbus-RTU通信协议解析、STM32程序实现及OLED显示,提供完整代码和调试技巧,适用于农业物联网环境监测系统。

kotlin6android的博客 339

el-upload自定义上传dwg/dxf文件并且携带额外参数(CAD)

需求:需要使用el-upload自定义上传cad的图片或普通图片,这边需要判断区分下,以及上传后清空上传文件列表。

请叫我欧皇!的博客 1535

Linux kernel:多个.c和.h文件编译成一个.ko模块

Linux系统中编写驱动程序,使用多个.c和.h源文件编译得到一个.ko模块,简单举例并编译运行。

baidu_38797690的博客 4092

MimicKit 人形机器人强化学习全身模仿控制算法使用教程

本文介绍了MimicKit运动模仿算法框架的使用指南。主要内容包括:1)安装IsaacGym和依赖项;2)训练模型命令及参数说明;3)测试模型的方法;4)分布式训练配置;5)使用TensorBoard可视化日志;6)动作数据格式说明。该框架支持DeepMimic、AMP、ASE、ADD等算法,包含PPO、AWR等强化学习算法,适用于物理仿真角色动画控制研究。

机器人控制与仿真应用 1202

linux编译驱动 多个文件,多个*.c文件编译生成一个模块驱动*.ko的makefile文件编写...

在加载自己写的3.1.4内核的adc驱动时,频频出现下面的错误提示,以前在2.6.29的内核上从未碰到:[root@LK2440 drivers]# insmod /lib/modules/adc.koadc: module license 'unspecified' taints kernel.Disabling lock debugging due to kernel taintadc: Un...

weixin_39969060的博客 1475

自定义Usecase/Pipeline

Summary of Custom Usecase and Pipeline Configuration in SA8650 QCX Framework This article elaborates on the complete process of customizing a new Usecase and Pipeline based on the SA8650 QCX framework to meet OEM and Tier1 customization requirements, with

qq_39257814的博客 929

15、降维算法:原理、实现与应用

本文深入介绍了多种降维算法,包括线性方法如主成分分析(PCA)和线性判别分析(LDA),以及非线性方法如Sammon映射、t分布随机邻域嵌入(t-SNE)和自编码器。文章通过C++库Dlib和Shogun展示了这些算法的具体实现,并结合图像压缩和数据可视化等实际案例,分析了不同算法的适用场景。此外,还探讨了降维算法的选择策略、优化改进方法以及未来发展趋势,为读者提供了全面的技术理解和应用指导。

lemon的博客 116

c文件如何编译为ko的MAKEFILE文件编写

首先需要知道:上面两者的区别在于,前者才会生成ko文件,后者只是代码编译进内核,并不生成ko文件。生成KO文件,分两种情况:单个.c文件和多个.c文件kernel配置文件中定义注意上面的m,表示作为一个模块进行编译,最后在MAKEFILE中需要用到的编译开关。

u010823818的博客 1081

三模冗余、纠错编码、单粒子翻转防护

本文探讨了高可靠性FPGA系统设计的三大关键技术:三模冗余(TMR)、纠错编码(ECC)和单粒子翻转(SEU)防护。TMR通过三个并行模块和表决器实现容错,但会增加硬件资源和功耗;ECC利用汉明码等编码方式检测和纠正数据错误,适用于存储器保护;SEU防护则针对高能粒子引发的位翻转问题,采用配置刷新、TMR和ECC等方法。文章还通过Verilog代码示例展示了这些技术的实现,并提出了一个综合应用案例,结合三种技术构建高可靠性控制系统。这些技术在航空航天、医疗设备等关键领域具有重要应用价值。

2301_79143213的博客 715

.c文件如何编译为ko的MAKEFILE文件编写

首先需要知道: obj-m = *.o obj-y = *.o 上面两者的区别在于,前者才会生成ko文件,后者只是代码编译进内核,并不生成ko文件。 生成KO文件,分两种情况:单个.c文件和多个.c文件【以展讯7730 ANDROID4.4为例】 1.单个.c文件 kernel配置文件中定义 CONFIG_RUNYEE_CAMVIB=m 注意上面的m,表示作为一个模块进行编译,

youngyang的专栏 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Linux内核驱动将多个C文件编译成一个ko文件的方法——每个C文件里都有module_init与module_exit,moduleinit

Linux内核驱动将多个C文件编译成一个ko文件的方法——每个C文件里都有module_init与module_exit,moduleinit 以两个C文件为例: 将本该被分别编译成adc_device.ko和adc_driver.ko的adc_device.c、adc_driver.c编译成一个ko文件! 采用方法: 第一步、修改C文件 1、去掉adc_device.c文件里

lqxandroid2012的专栏 3250

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)

【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)

challenglistic的博客 9212

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

linux .c编译成.ko文件,makefile多个*.c 、*.h文件编译成.ko文件

编译wifi模块时,改用多个*.c、*.h进行编译成单个.ko文件。Makefile 文件如下:#!/bin/bashobj-m += mtk_hif_sdio.occflags-y += -I$(src)/linux/include -I$(src)/core/include -I$(src)/includeKDIR := /home/kernel/iTop4412_Kernel_3.0_lin...

weixin_35798040的博客 565

linux根据设备加载模块,Linux内核设备驱动之Linux内核模块加载机制笔记整理

#include 1. 模块参数在驱动定义变量static int num = 0; //当加载模块不指定num的值时则为0module_param(变量名, 类型, 权限);类型: byte, int, uint, short, ushort, long, ulong, bool, charp,权限不能有写的权限传参数: insmod test.ko 变量名1=值1 变量名2=值2module...

weixin_35004618的博客 136
上一篇: insmod: ERROR: could not insert module exp.ko: Unknown symbol in module
下一篇: 栈空间与堆空间
SweeNeil
博客等级 码龄9年 251粉丝 86原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值