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

代码编写

第一个.c源文件命名为test.c,其中只有一个函数,在内核中打印一句"hello world!"。

// test.c
// --------------------------------

#include "test.h"

void test(void)
{
	printk("hello world!\n");
	return;
}

第二个.c源文件命名为main.c,其中包含了模块加载和卸载部分。模块加载和卸载时各有一句打印,同时在模块加载时,调用了第一个源文件中的test()函数。

// main.c
// --------------------------------

#include "test.h"

static int hello_init(void)
{
	printk("hello init!\n");
	test();
	return 0;
}

static void hello_exit(void)
{
	printk("hello exit!\n");
	return;
}

module_init(hello_init);
module_exit(hello_exit);

编写一个头文件test.h,包括必要的头文件、协议和作者声明、函数声明。

// test.h
// --------------------------------

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("z_mss");

void test(void);

编写Makefile文件,内容如下。

ifneq ($(KERNELRELEASE),)
	obj-m := model.o
	model-objs := main.o test.o
else
	KDIR	:= /lib/modules/$(shell uname -r)/build
	PWD		:= $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean
endif

内核模块的Makefile编写方法请参考我的这篇博客,这具体解释一下这个Makefile的特别之处,即如何将多个源文件编译在一起。

obj-m参数指定最后得到的.ko文件来自于model.o文件,即由model.o生成model.ko文件。

model-objs参数指定了model.o的来源,来自于main.o和test.o,而main.o和test.o默认由main.c和test.c分别编译得到。注意,model-objs这个名字是不固定的,假设我们最后将.ko的名字改为命名成model_1.ko,则Makefile就要做出下面的相应修改。

ifneq ($(KERNELRELEASE),)
	obj-m := model_1.o
	model_1-objs := main.o test.o

编译运行

输入make指令编译一下。

sudo -s指令进入root模式。

insmod指令加载模块,dmesg查看一下内核打印,可以看到成功加载了模块并调用了另一个源文件下的test函数。

rmmod指令移除模块,dmesg查看打印,可以看到成功移除了模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值