关闭

第二章:构造和允许模块(part1)

150人阅读 评论(0) 收藏 举报

注:这是当初学习《linux设备驱动程序》的学习笔记,只有提纲挈领的作用,不足之处还请大家多多包涵,多多指点。

Hello world模块

模块能够调用printk是因为在insmod函数装入模块之后,模块就连接到了内核,可以访问内核的公用符号。

printk( KERN_ALERT” Hello world.\n”);

优先级只是一个字符串,如<1>,该字符串置于printk格式字符串的前面。注意KERN_ALERT之后并不适用逗号。

核心模块和应用程序的对比

² 应用程序在退出时,可以不管资源的释放或者其他的清楚工作,但模块的退出函数却必须仔细撤销初始化函数所做的一切,否则,在系统重新引导之前某些东西就会残留在系统中。

² printkprintf最大的不同在于它缺乏对浮点数的支持。

² 编写模块代码用到的大多数头文件都在include/linuxinclude/asm目录中,include其他的子目录保存有和特定子系统相关的头文件。

用户空间和内核空间

² 模块运行在所谓的内核空间,而应用程序运行在所谓的用户空间。

² 内核空间和用户空间都有自己的内存映射,也即自己的地址空间。

² 一个驱动程序要执行两种任务:某些函数作为系统调用的一部分而执行,其他函数负责中断处理。

内核中的并发

Linux内核代码(包括驱动程序代码)必须是可重入的。

常见错误:认为只要某段代码没有进入睡眠状态(或者阻塞),就不会产生并发问题。

当前进程

内核代码可通过全局项current来获得当前进程。current<asm.current.h>中定义,是一个指向struct task_struct的指针,task_struct结构在<linux/sched.h>文件中定义。current指针指向当前正在运行的程序,在openread等系统调用的执行过程中,当前进程指的是调用这些系统调用的进程。

设备驱动程序只要包含<linux/sched.h>头文件即可引用当前进程。如:

printk(KERN_INFO “The process is \” %s \” (pid %i) \n”, current->comm, current->pid);

current->comm中式当前进程所执行的程序文件的基本名称。

其他的一些细节

内核栈非常小。

内核API中看到具有两个下划线(__)的函数名称。这种函数通常是接口的底层组件,应谨慎使用。

内核代码不能实现浮点数运算。

编译和装载

编译模块

如果我们邀构造的模块名称为module.ko,并由两个源文件(如file1.cfile2.c)生成,则正确的makefile可以编写如下:

obj-m := module.o

module-objs := file1.o file2.o

如果内核源代码树保存在~/kernel-2.6目录中,则用来构造模块的make命令应该是(在包含模块源代码和makefile的目录中键入)

make –C ~/kernel-2.6 M=’pwd’ modules

装载和卸载模块

insmod将模块的代码和数据装入内核,然后使用内核的符号表解析模块中任何为解析的符号。它和ld(链接器)不同,内核不会修改模块的磁盘文件,仅仅修改内存中的副本。

insmod可以接受一些命令行选项,并且可以在加载模块是为其中的整形和字符串型变量赋值。

insmod依赖于定义在kernel/module.c中的一个系统调用。函数sys_init_mudule给模块分配内核内存(vmalloc负责),然后该系统调用将模块正文复制到内存区域,并用内核符号表解析模块中的内核引用,最后调用模块的初始化函数。
modprobe工具:和insmod类似,用来装载模块。和insmod的区别:modprobe会考虑要装载的模块是否引用了一些当前内核不存在的符号,如果有,则在当前模块搜索路径上查找定义了这些符号的其他模块,若找到(即要装载模块所以来的其他模块),则modprobe同时将这些模块装载到内核。insmod在这种情况下会失败,并且在系统日志中记录”unresolved symbols ” 消息。系统日志文件(/var/log/messages

lsmod程序:列出了当前装载到内核的所有模块。它通过读取/proc/modules虚拟文件来获得这些信息。

版本依赖

linux/version.h自动包含于linux/module.h中,其中的一些宏:

² UTS_RELEASE

扩展为一个描述内核版本的字符串,如”2.6.10”。

² LINUX_VERSION_CODE

扩展为内核版本的二进制表示,版本发行号的每一部分对应一个字节。如2.6.10对应的 是132618(0x02060a)

² KERNEL_VERSION(major, minor, release)

以组成版本号的三部分为参数,创建证书的版本号。KERNEL_VERSION(2,6,10)扩展为132618

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13554次
    • 积分:288
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章存档