驱动程序的模块化编程

Linux的内核非常庞大,包含了很多的组件,我们通常有两种办法在内核中加入我们需要的功能。

第一种:把所有需要的功能都编译到内核中

这种方法对导致两个问题:一是生成的内核会很大。二是如果我们要在现有的内核中新增或删除功能,不得不重新编译内核,效率很低。而且如果我们编写的内核不完善的话很有可能会造成内核崩溃。

第二种:把需要的功能编译成单独的模块

Linux提供了模块这种机制。是我们可以实现编译出的内核本身并不包含所有功能,而在需要这些功能时,功能对应的代码可以被动态的加载到内核中。

注意:模块并不是驱动的必要形式,即:模块不一定必须是模块,有些驱动是直接编译进内核的;同时模块也不全是驱动,例如:我们写的一些很小的算法也可以作为模块加载进内核,但它并不是驱动。

一个简单的模块例子:

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

int hello_init(void)
{
	printk("hello_init()\n");
	return 0;
}
void hello_exit()
{
	printk("hello_exit()\n");
	return;
}
module_init(hello_init);
module_exit(hello_exit);

编译上述模块需要的makefile:

ifneq  ($(KERNELRELEASE),)
$(info "2nd")
obj-m:=hello.o
else
KDIR := /lib/modules/$(shell uname -r)/build  //内核路径,根据实际情况转换成自己的内核路径
PWD:= $(shell pwd)
all:
	$(info "1st")
	make -C $(KDIR) M=$(PWD) modules  //-C表示进入KDIR表示的目录执行makefile,M=  表示返回PWD目录再执行makefile
clean:
	rm -r *.ko *.o  *.mod.c *.order *.symvers
endif

最终会编译得到hello.ko文件,使用insmod  xxx.ko把模块插入内核,然后使用dmesg即可查看输出提示信息,即我们printk打印出的信息。


我们可以用_init和_exit来修饰函数,这是系统提供的两种宏,表示所修饰的函数在调用完成后会自动回收内存,即内核认为这种函数只会被执行一次,然后他所占用的资源就会被释放。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值