Chinaunix首页 | 论坛 | 博客
  • 博客访问: 81928
  • 博文数量: 19
  • 博客积分: 575
  • 博客等级: 中士
  • 技术积分: 203
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-03 20:06
个人简介

好好学习,天天向上

文章分类

全部博文(19)

分类: LINUX

2011-04-06 18:05:40

LDD3笔记)

驱动可以编译为模块,也可以静态编译到内核中,调试的时候一般作为模块。

一个最基本的模块

hello.c:

#include

#include

 

static int __init hello_init(void)

{

  printk(KERN_ALERT "hello world init!\n");

  return 0;

}

 

static void __exit hello_exit(void)

{

  printk(KERN_ALERT "hello world exit!\n");

}

 

module_init(hello_init);

module_exit(hello_exit);

 

Makefile:

obj-m := hello.o

KDIR := /home/linux-2.6.9

PWD := $(shell pwd)

default:

  $(MAKE) -C $(KDIR) M=$(PWD) modules

.PHONY:clean

clean:

  -rm *.o *.ko

 

make之前,你得有内核源码,比如我的是/home/linux-2.6.9,而且应该在源码下make menuconfig一次,再make modules(可以中途结束掉,这是为了产生modpost工具)。

之后再cd到测试模块目录,make就可以在当前目录下产生hello.ko模块文件。

如果你的内核源码和你的linux内核版本一致,你就可以用insmod hello.ko挂载模块了,然后你会在系统日志中看到hello world init等信息,如果版本不一致,就会看到如下错误信息:insmod: error inserting 'hello.ko': -1 Invalid module format

你可以使用uname –r查看当前系统内核的版本信息,然后再去下载相应的内核源码。

 

总结:

       在学习开发驱动之前,你要有对应自己linux的内核源代码(kernel.org上下载)。

       模块使用module_init注册,使用module_exit退出

       内核可以使用printk打印信息

       加载模块的工具有insmod, modprob,卸载模块的工具:rmmod

       查看模块信息:modinfo xxx

 

给模块添加信息

我们可以给自己的模块添加版权,作者等信息,通过使用下面的宏来实现:

MODULE_AUTHOR(author);

MODULE_DESCRIPTION(description); //关于模块做什么的声明

MODULE_VERSION(version_string); //一个代码修订版本号

MODULE_DEVICE_TABLE(table_info); //来告知用户空间, 模块支持那些设备

MODULE_ALIAS(alternate_name); //模块为人所知的另一个名字

MODULE_LICENSE(license);

 

修改hello.c:

#include

#include

 

static int __init hello_init(void)

{

  printk(KERN_ALERT "hello world init!\n");

  return 0;

}

 

static void __exit hello_exit(void)

{

  printk(KERN_ALERT "hello world exit!\n");

}

 

module_init(hello_init);

module_exit(hello_exit);

 

MODULE_AUTHOR("crazycode");

 

重新make后,用modinfo查看模块信息:modinfo hello.ko

filename:       hello.ko

author:         crazycode

vermagic:       2.6.32 SMP mod_unload modversions 686 4KSTACKS

depends:

 

导出符号

如果想使自己模块的函数或者变量在模块外部可见,可以使用:

EXPORT_SYMBOL(name);EXPORT_SYMBOL_GPL(name);//仅定义了licenseGPL的模块可见

 

模块参数

#include

module_param(variable, type, perm);

module_param_array(name,type,num,perm);

创建模块参数, 可以被用户在模块加载时调整( 或者在启动时间, 对于内嵌代码).

类型type可以是 bool, charp, int, invbool, short, ushort, uint, ulong, 或者 intarray.

num是数组元素的个数

权限perm定义在里,指明访问参数的权限

#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)

#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)

#define S_IRUGO   (S_IRUSR|S_IRGRP|S_IROTH)

#define S_IWUGO   (S_IWUSR|S_IWGRP|S_IWOTH)

#define S_IXUGO   (S_IXUSR|S_IXGRP|S_IXOTH)

hello模块添加参数:

hello.c

#include

#include

#include

 

static char *name="crazy";

static int times=1;

module_param(name,charp,S_IRUGO);

module_param(times,int,S_IRUGO);

 

static int __init hello_init(void)

{

  int i;

  printk(KERN_ALERT "hello world init!\n");

  for(i=0;i

    printk("welcome %s !\n",name);

  return 0;

}

 

static void __exit hello_exit(void)

{

  printk(KERN_ALERT "hello world exit!\n");

}

 

module_init(hello_init);

module_exit(hello_exit);

 

MODULE_AUTHOR("crazycode");

重新make之后,加载它:insmod hello.ko name=”crazycode” times=5

然后在系统日志中可以看到:

Apr  6 06:16:57 localhost kernel: welcome ”crazycode” !

Apr  6 06:16:57 localhost last message repeated 4 times

阅读(1888) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~