Chinaunix首页 | 论坛 | 博客
  • 博客访问: 100179
  • 博文数量: 64
  • 博客积分: 3050
  • 博客等级: 中校
  • 技术积分: 725
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-22 18:16
文章分类
文章存档

2010年(56)

2009年(8)

我的朋友

分类: LINUX

2010-01-04 11:38:32

内核需要自己单独的打印输出函数,这是因为她在运行时不能依赖于C库。
 
printk(KERN_ALERT "Hello, world\n");  //注意KERN_ALERT后面并不使用逗号。
我们需要在模块代码中显示地制定高优先级的原因在于:具有默认优先级的消息可能不会输出在控制台上
 
内核模块和应用程序的对比:
1·大多数中小规模的应用程序是从头到尾执行单个任务
  而模块却只是预先注册自己以便服务于将来的某个请求,然后它的初始化函数就立即结束。(模块初始化函数的任务就是为了以后调用模块函数预先做准备)
2·应用程序在退出时,可以不管资源的释放或者其他的清除工作
  模块的退出函数却必须仔细撤销初始化函数所做的一切,否则,在系统重新引导之前某些东西就会残留在系统中。
3·在各种环境下处理错误的方式不同:
  应用程序开发过程中的段错误是无害的,并且总是可以使用调试器跟踪到原代码的问题所在
  一个内核错误即使不影响整个系统,至少也会杀死当前进程。
我们通常将运行模式称作内核空间用户空间。这两个术语不仅说明两种模式具有不同的优先权等级,而且还说明每个模式都有自己的内存映射,也即自己的地址空间
 
内核代码可以通过current获得与当前进程相关的信息,current在中定义,是一个指向struct task_struct的指针, task_struct结构在文件中定义。
设备驱动程序只要包含头文件就可以引用当前进程。
存储在current->comm成员中的命令是当前进程所执行的程序文件的基本名称。
printk(KERN_INFO "The process is \"%s\" (pid %i)\n",current->comm, current->pid);
 
 
读者经常会在内核API中看到具有两个下划线前缀(--)的函数名称。具有这种名称的函数通常是接口的底层组件。双下划线告诉程序员:谨慎使用,后果自负。
 
内核代码不能实现浮点数运算,内核代码中也不需要浮点运算。
 
有且只有系统调用的名字前带有sys_前缀。
 
使用rmmod工具从内核中移除模块,注意:如果内核认为模块仍然在使用状态,或者内核被配置为禁止移除模块,则无法移除该模块。
 

有几个头文件是专门用于模块的,必须出现在每个可装载的模块中。

#include   module.h包含有可装载模块需要的大量符号和函数的定义

#include   包含init.h的目的是制定初始化和清除函数

大部分模块还包括moduleparam.h头文件,使得我们可以在装载模块时向模块传递参数
 

初始化函数

static int __init initialization_function(void)

{````初始化代码·····`}

module_init(initialization_function);

初始化函数应该被声明为static,因为这种函数在特定文件之外没有其他意义。

__init表明该函数仅在初始化期间使用。在模块被装载之后,模块装载器就会将初始化函数丢掉,这样可以将该函数占用的内存释放出来。

module_init的使用是强制性的。没这个定义,初始化函数永远不会被调用。

 
大部分注册函数名字带有register_前缀
 
清除函数

每个重要的模块都需要一个清除函数,该函数在模块被移除前注销接口并向系统中返回所有资源。

清除函数没有返回值,因此被声明为void

__exit修饰词标记该代码仅用于模块卸载。如果模块被直接内嵌到内核中,或者内核的配置不允许卸载模块,则被标记为__exit的函数将被简单的丢弃

如果一个模块未定义清除函数,则内核不允许卸载该模块。

 
 
在用来支持某个设施的所有内部初始化完成之前,不要注册任何设施。
 
 
模块参数

在insmod改变模块参数之前,模块必须让insmod命令看见这些参数。

参数必须使用module_param宏来声明,这个宏在moduleparam.h中定义。module_param需要三个参数:变量的名称,类型以及用于sysfs入口项的访问许可掩码(perm)。  这个宏必须放在任何函数之外,通常是在源文件的头部。

static char *whom = "world";

static int howmany = 1;

module_param(howmany,int,S_IRUGO);

module_param(whom,charp,S_IRUGO);

charp是内核支持的模块参数类型:字符指针值。内核会为用户提供的字符串分配内存,并相应的设置指针。

perm:如果对参数使用S_IRUGO,则任何人均可读取该参数,但不能修改;如果perm被设置为0,就不会有对应的sysfs入口项;S_IRUGO|S_IWUSR允许root用户修改该参数。

 

模块装载器也支持数字参数

module_param_array(name,type,num,perm);

name是数组的名称(也就是参数的名称),type是数组元素的类型,num会被设置为用户提供的值的个数,perm是常见的访问许可值。

 

 
 
 
阅读(387) | 评论(0) | 转发(0) |
0

上一篇:10.01.03

下一篇:10.01.04

给主人留下些什么吧!~~