linux驱动05:编译与装载

本文介绍内核模块的基础知识,包括Makefile编译、insmod和modprobe装载、rmmod卸载及lsmod查看已装载模块的方法。同时探讨了模块与内核版本及平台的依赖关系。

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

一、编译

Makefile

#如果已定义KERNELRELEASE,则说明是从内核构造系统调用的,因此可利用其内建语句。
ifneq ($(KERNELRELEASE),)
obj-m := hello.o

#否则是直接从命令行调用的,这时要调用内核构造系统。
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order
endif

如果要构造的模块名称为module.ko,由两个源文件生成(如file1.c file2.c),则:

obj-m := module.o

module-objs := file1.o file2.o

该Makefile将被读取两次

第一次:当Makefile从命令行调用时,KERNELRELEASE变量尚未设置,读取else部分。获取内核源代码树;调用all:目标,第二次运行make,以便运行内核构造系统。

第二次:读取ifneq部分,设置obj-m。内核Makefile负责真正构造模块。

二、装载

insmod

依赖于定义在kernel/module.c中的一个系统调用;

流程:

sys_init_module给模块分配内存;该系统调用将模块正文复制到内存区域,并通过内核符号表解析模块中的内核引用,最后调用模块的初始化函数。

modprobe

和insmod类似,也是用来将模块装载到内核中,区别在于,它会考虑要装载的模块是否引用了一些当前内核不存在的模块。

rmmod

从内核中移除模块。

lsmod

列出当前装载到内核中的所有模块;lsmod通过读取/proc/modules虚拟文件来获取信息;有关当前已装载模块的信息可以在sysfs虚拟文件系统的/sys/module下找到。

三、版本依赖

构造过程中,可以将模块和当前内核树中的一个文件(vermagic.o)链接;该文件包含了大量的有关内核的信息,如内核版本、编译器版本以及一些重要配置变量的设置。在装载模块时,这些信息可用来检查模块和正在运行的内核的兼容性,如果不匹配,就不会装载该模块。(invalid module format)

特定的内核版本编译模块,需要对应的构造系统和源代码树,修改Makefile中KERNELDIR变量即可。

编写一个能够和多个内核版本一起工作的模块,必须使用宏以及#ifdef来构造并编译代码。可使用linux/version.h中的相关宏定义:

LINUX_VERSION_CODE        内核版本的二进制表示

KERNEL_VERSION(major, minor, release)        以组成版本号的三个整数为参数创建版本号

如:

版本号:2.6.10  

LINUX_VERSION_CODE 132618 

KERNEL_VERSION(2, 6, 10)   132618

通过检查KERNEL_VERSION和LINUX_VERSION_CODE而使用预处理条件,可以解决大部分基于内核版本的依赖性问题。

四、平台依赖

编译时链接vermagic.o

在装载模块时,内核会检查处理器相关的配置选项以便确保模块匹配于运行中的内核;如果模块在不同的选项下编译,则不会装载模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值