Linux驱动开发之模块化驱动结构

本文探讨了驱动模块化的必要性,介绍了内核驱动模块的基本构成,包括加载与卸载函数、许可证声明及设备操作。还详细说明了如何通过Makefile编译模块并演示了简单的示例。

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

一、为什么要将驱动模块化

      要把编写的驱动程序包含到内核中,主要有两种方法:

1> 把所有需要的功能都编译到Linux内核

     主要问题:会导致生成的内核很大,而且如果要在现有内核中新增或删除功能,要重新编译内核代码。

2> 把新的驱动内容做成一个独立的模块,在需要时加载到内核中

      主要特点:模块本身不会被编译到内核映像,只需要在使用时加载到内核中。模块一旦被加载,它就和内核中的其他部分完全一样。

二、内核驱动模块的组成

       一个最简单的内核驱动模块只需要包含模块加载函数、卸载函数、GPL许可权限声明以及一些描述信息即可。内核驱动模块编译后会生成  xxx.ko  文件,可以直接使用  insmod  xxx.ko  即可将其加载到内核中。使用  rmmod xxx.ko  即可将其从内核中卸载。

例如:

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

static int __init xxx_init(void)
{
    printk("我是模块加载函数\n");
    return 0;
}

static void __exit xxx_exit(void)
{
    printk("我是模块卸载函数\n");
}

module_init(xxx_init);
module_exit(xxx_exit);
MODULE_LINCESE("GPL");

 在上述代码中,printk()函数用于输出内核中的信息,类似于用户空间中使用printf()。可以通过 lsmod命令查看系统已加载的所有模块,类似于Linux中的ls命令。

在模块加载函数中,一般要完成设备号申请、创建设备文件、实现设备操作接口函数、硬件初始化等步骤。与之对应,在卸载函数中完成加载函数的反操作,即释放设备号、销毁设备文件等。

三、内核驱动模块的编译

       一般使用Makefile进行管理和编译内核驱动模块,对于这个简单内核驱动模块,编写一个Makefile进行编译,假设上述模块保存为  xxx.c 

KERNEL_DIR = /home/linux/linux-4.4.249/  #Linux内核所在目录
CUR_DIR = $(shell pwd)  #当前目录

obj-m := xxx.o
make = -C $(KERNEL_DIR) M=$(CUR_DIR)modules

编写好Makefile后,直接在当前目录make即可生成驱动目标文件 xxx.ko

之后,直接使用  insmod  xxx.ko  即可将其加载到内核中。至此,一个最简单的内核驱动模块便已完成,后续会继续更新包括接口函数的实现、平台总线写驱动等内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值