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

原创 2012年03月29日 11:09:50

注:这是当初学习《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

 

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

内核符号表 当模块被装入内核后,它所导出的任何符号都会变成内核符号表的一部分。 模块层叠技术是一个常用的方案。modprobe是处理层叠模块的一个使用工具,它除了装入指定模块外还同时装入了指定模块...
  • ljp827
  • ljp827
  • 2012年03月29日 11:19
  • 240

第二章 构造和运行模块(1)

第二章开始进入到实际的编程了。第一个测试代码:Hello World。 第一件事就是建立测试系统。 我安装的系统是rhel-5.1-server-i386-dvd.iso,你可以到网上下载其他版本...

Android数据库ORMlite框架翻译系列(第二章:part 1)

前言 由于第二章是整个文档的核心,内容也很多,所以分次翻译。下一章的内容会继续本章接着翻译。 ---------------------------------------------------...
  • QQzyb
  • QQzyb
  • 2013年12月12日 16:43
  • 785

day3 part1:《Thinking in Java》笔记第二章---一切都是对象

Java是基于C++的,但比C++是更纯粹的面向对象程序设计语言(OOP) 用引用操纵对象:Java中所有一切都被看成对象,实质上操纵的标识符是对象的一个引用(reference),引用可以在无对象时...

getting start with storm 翻译 第二章 part-1

第二章 开始 在本章中,我们会建一个storm工程和我们的第一个storm topology。  下述假设你安装了至少1.6版本的Java运行时环境(JRE)。我们推荐使用oracle提供的JRE,可...

Android数据库ORMlite框架翻译系列(第二章:part 1)

前言 由于第二章是整个文档的核心,内容也很多,所以分次翻译。下一章的内容会继续本章接着翻译。 -----------------------------------------------...

LDD3笔记:第二章 构造和运行模块

在正式进行驱动开发前,需要了解有关模块编程和内核编程的一些基本概念。在本节中将会构造几个完整的(但绝对没啥功用的)模块。设置测试系统一般的发行版本都会装好内核代码树的,用过的Red Hat Enter...

第二章 构造和运行模块(笔记)

1. 设置测试系统 如果读者正在编写一个只适用于某特定发行版的驱动程序,则应该针对相关内核创建和测试自己的驱动程序。 2.6.x内核构造模块,必须在自己的系统中配置并构造好内核树(因为2.6内核的...

【Linux 驱动】第二章 构造和运行模块

设置测试系统开发环境及Hello World入门模块在前面博文中已经讲到,请参考http://blog.csdn.net/tianshuai11/article/details/7442168   ...

Excel VBA高效办公应用-第二章-Excel VBA编辑基础-Part1(VBA关键字)

VBA常用关键字有: And Arrary As Binary Boolean Byref Byval Case Currency Date Dim Do Double Else Empty End ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第二章:构造和允许模块(part1)
举报原因:
原因补充:

(最多只允许输入30个字)