编译驱动ko,多个.c文件情况下,怎么写makefile

本文主要介绍了Linux下makefile脚本相关内容,包括定位内核源码目录、模块建立规则等,还说明了多个C文件构造模块时的命名问题。此外,提到生成ko模块后,可使用strip命令查看和删除调试信息,为ko文件瘦身。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、makefile脚本

KERN_DIR = ../../linux-4.9.84/
ARCH := arm
CROSS_COMPILE := arm-buildroot-linux-uclibcgnueabihf-
EXTRA_CFLAGS += -Werror
MODULE_NAME = alex_main

EXTRA_CFLAGS += -I$(PWD)/include/kernel -I$(PWD)/include/usr
EXTRA_LDFLAGS += --strip-debug
EXTRA_CFLAGS += -Werror

$(CONFIG_MS_GPIO)=y

obj-m += ${MODULE_NAME}.o

${MODULE_NAME}-y += radio/radio.o
${MODULE_NAME}-$(CONFIG_MS_GPIO) += maindev.o

$(MODULE_NAME)-objs += alex.o

.PHONY: modules clean

modules:
	make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(shell pwd) modules

clean:
	rm -rf *.ko *.o *.mod.c *.mod.o */*.o
	rm -f modules.order
	rm -f Module.symvers
	rm -rf .tmp_versions
	rm -f .*o.cmd */.*.o.cmd

(1)KERN_DIR = ../../linux-4.9.84/
 用来定位用于编译驱动的内核源码的目录位置。可以用下面的格式传递进去

make -C ../../linux-4.9.84/

(2)-C表示kernel source目录,PC机上对应的目录/lib/modules/<uname -r>/build(在这里可以找到kernel最高级的makefile),M=表示在建立模块target的时候,makefile回归到我们模块程序的目录。

(3)obj-m := ${MODULE_NAME}.o
表面驱动模块从目标文件${MODULE_NAME}.o建立,从目标文件建立后,模块的名字为${MODULE_NAME}.ko

(4)${MODULE_NAME}-$(CONFIG_MS_GPIO) += maindev.o
如果模块由N个文件组成,那么其他文件就应该描述如下:${MODULE_NAME}-y += file1.o file2.o。可以通过选择CONFIG_MS_GPIO是y还是n选择是否编译后面的文件 。

(5)如果我们有多个c文件,$(MODULE_NAME)-objs += file1.o file2 alex.o 可以以这种方式添加。其中-objs前面的参数是模块名。在test-objs参数中加入他们的obj文件。接下来就是make了,编译后,生成hello.o文件和hello.ko,还有hello.mod.c及其obj文件,Module.markers Module.sysvers Modules.order 文件。
        此处对多个*.c文件情况做一个说明:我们希望创建一个模块的名字叫做hello,我们有三个*.c文件,分别为hello.c, file1.c和file2.c。这样是有问题的,因为在Makefile中obj-m := hello.o,这是指定模块的名称。hello-objs := file1.o file2.o hello.o,这里是说hello模块包括的的obj文件,如果我们在里面不填写hello.o,那么实际并没有编译hello.c。如果我们在这里填写了hello.o,那么在obj-m和hello-objs中都含有hello.o,对make来讲会产生循环和混淆,因此也不能这样书写。如果由多个C文件来构造一个模块,那么C文件的名字不能和模块名字一样。在这个例子中可以将hello.c改名为hello_main.c,在Makefile中obj-m := hello.o,hello-objs = file1.o file2.o hello_main.o。

二、生成ko模块后的处理
        ko文件生成后一般都包含各种调试信息,以下命令可以查看。发布产品时,需要使用strip命名删除调试信息,给ko文件瘦身。

readelf -s xxx.ko
strip:
    $(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded --strip-debug

--strip-debug
        Remove debugging symbols only.
--strip-unneeded
        Remove all symbols that are not needed for relocation processing.

参考博客

https://blog.youkuaiyun.com/zengxianyang/article/details/50710695

https://blog.youkuaiyun.com/p1279030826/article/details/108040129

Linux内核中,通常有许多头文件和源文件需要编译.ko(内核对象)文件,以实现对特定功能或驱动程序的支持。 首先,头文件包含了函数和数据结构的声明,被其他源文件引用。这些头文件通常以.h文件扩展名结尾。源文件则包含了函数和数据结构的实现,通常以.c或.cpp文件扩展名结尾。 为了将多个文件和源文件编译.ko文件,使用Makefile是一个常见的方法。Makefile是一个文本文件,包含了一系列的规则,指定了文件的依赖关系以及编译和链接的命令。 Makefile中的规则通常包括以下几个步骤: 1. 定义目标文件.ko文件)的名称和相关的编译选项。 2. 定义依赖关系,即指定哪些源文件和头文件需要进行编译。 3. 定义编译命令,通常使用gcc或其他编译器执行编译操作。例如,可以使用gcc -c命令将源文件编译成目标文件.o文件)。 4. 定义链接命令,将所有目标文件链接成一个.ko文件。例如,可以使用gcc -o命令将所有目标文件链接成一个.ko文件。 在执行Makefile时,会根据规则的定义逐步执行编译和链接的操作,生成最终的.ko文件。同时,Makefile还可用于指定其他操作,例如清除中间文件或执行其他自定义操作。 总而言之,将多个文件和源文件编译.ko文件可以通过使用Makefile来定义编译和链接的规则,并将其作为输入参数传递给编译器。Makefile中的规则会根据文件的依赖关系逐步执行编译和链接的操作,最终生成所需的.ko文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值