LDD3:第二章 构造和运行模块 摘抄与思考

阅读O'REILLY的《Linux设备驱动程序(第三版)》第二章感觉有很多之前学习驱动时忽略的内容,之前不求甚解只求先观其全貌,错失了很多细节,经过LDD3的阅读,简单记录其中自己觉得有意思的内容,以及自己的一些思考。

加粗标红为原书的内容,以及每个问题都会附带内容所在页面

1、为什么驱动模块能够调用库函数如printk——P23

“模块能够调用printk是因为在insmod函数装入模块后,模块就连接到了内核,因此可以访问内核的公用符号(包括函数和变量)”

根据《程序员的自我修养》书中介绍,程序应该在静态链接过程中,将需要用到的符号地址进行指定,如果是动态链接,则会在指定库中找到对应的函数地址,进行调用。

对于驱动模块而言,可以类比用户程序。

2、printk和printf的区别——p24

”printk函数就是有内核定义并导出给模块使用的的一个printf的内核版本,除了几个细小差别以外,他们功能类似,最大的不同是printk缺乏对浮点数的支持“

内核基本不需要使用浮点运算。

3、模块是否会和函数库链接,即使用普通函数库的头文件——p24

"没有任何函数库会和模块链接,因此,源文件(模块)中不能包含通用的头文件,像<stdarg.h>以及一些非常特殊的情况例外“

模块会使用include/linux和include/asm目录下,提供给内核相关的函数使用。

4、怎么获得当前进程——p27

”内核代码可以通过访问全局项current来获得当前进程“

current定义在<asm.current.h>,是一个指向struct task_struct 的指针。

5、内核的栈大小——p27

"内核具有非常小的栈,可能只和4096字节大小的页那样小”“如果需要大的结构,应该调用时动态分配该结构”

6、linux内核API中具有两个下划线前缀(__)的函数,通常是接口的底层组件,应该谨慎使用。

7、内核代码能够实现浮点运算——p28

"可以通过打开浮点支持,在某些架构上,需要在进入和退出内核空间时保存和恢复浮点处理器的状态。这种额外的开销没有任何价值,内核代码中也不需要浮点运算。”

8、内核如何支持insmod工作——p30

”insmod依赖于定义在kernel/module.c中的一个系统调用。函数sys_init_module给模块:

1、分配内核内存(vmalloc负责内存分配)以便装载模块。

2、将模块正文复制到内存区域

3、通过内核符号表解析模块中的内核应用

4、调用模块的初始化函数“

9、系统调用名字前带有sys_前缀

10、modprobe和insmod的区别——p31

"modprobe要考虑要装载的模块是否引用了一些当前内核不存在的符号。如果有这类引用,modprobe会在当前模块搜索路径中查找定义了这些符号的其他模块。如果modprobe找到了这些模块(即要装载的模块所依赖的模块),他会同时将这些模块装载到内核“

”如果在需要依赖其他模块的情况下使用insmod,则该命令会失败,并在系统日志文件中记录unresolved symbols(未解析的符号)消息。

11、模块装载失败的具体信息可以在系统日志文件/var/log/messages或者系统配置使用的文件查看。——p31

12、模块如何导出符号,即提供自身的变量和函数给其他模块使用——p34

EXPORT_SYMBOL(name); EXPORT_SYMBOL_GPL(name);

这两个宏均可将给定符号导出到模块外部。 _GPL版本使得要导出的模块只能在GPL许可证的模块下使用。

这两个宏会将变量在ELF中一个特殊部分存储,装载时,内核通过这个段来寻找模块导出的变量。

13、模块必须用到的头文件,专门用于模块——p35

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

14、module_init指定模块的入口,如何实现——p36

"module_init的使用是强制性的,这个宏会在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数所在的位置。没有这个定义,初始化函数永远不会被调用”

15、模块的清除函数是如何实现的——p37

"模块清除函数使用__exit修饰,__exit修饰词标记该代码仅用于模块卸载(编译器将把该函数放到特殊的ELF段中)。如果一个模块未定义清除函数,则内核不允许卸载该模块“

16、错误编码定义在哪里,表示的意思——p38

"错误编码是定义在<linux/errno.h>中的负整数,用用户程序可以通过perror函数或者类似的途径将他们转换为有意义的字符串“

17、模块加载时如何传入参数——p41

"在insmode改变模块参数之前,模块必须让这些参数对insmod命令可见,参数必须使用module_param宏来声明,该宏定义在moduleparam.h中。module_param需要三个参数:变量的名称、类型以及用于sysfs入口项的访问许可掩码,该宏需要放到任何函数之外,通常是源文件头部“

static char *whom = "world";

static int howmany = 1;

module_param(whom, charp, S_IRUGO);

module_param(howmany, int, S_IRUGO);

参数的类型:

bool,invbool(布尔值),charp(字符指针),int,long,short,uint,ulong,ushort,也可以用模块代码中的钩子来定义自定义类型。(参考moduleparam.h)

参数的访问许可掩码(定义在<linux/stat.h>):

S_IRUGO(任何人可读,不可修改) S_IRUGO|S_IWUSR(允许root用户修改) ...

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值