linux2.6 添加驱动,Linux2.6 驱动设计――从 2.4 到 2.6

Linux2.6 驱动设计――从 2.4 到 2.6

作者 Ray

RTEMS版权所有,转载请注明来源ray@rtems" target="_blank">www.rtems.net,作者ray@rtems

Linux 2.6 和 2.4 的比较我不想废话,总体来说 2.6 功能更强,但是资源消耗更多。

由于 2.6 内核在驱动框架,底层调用上和 2.4 内核有很多差别,所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。

2.6 和 2.4 主要的不同在于

? 内核的 API 变化,增加了不少新功能(例如 mem pool )

? 提供 sysfs 用于描述设备树

? 驱动模块从 .o 变为 .ko

移植 hello word

下面是一个最简单的 2.4 驱动:

#define MODULE

#include

#include

int init_module(void)

{

printk(KERN_INFO "Hello, world\n");

return 0;

}

void cleanup_module(void)

{

printk(KERN_INFO "Goodbye cruel world\n");

}

2.6的hello world版本!

#include < linux/module.h>

#include < linux/config.h>

#include < linux/init.h>

MODULE_LICENSE("GPL");// 新,否则有 waring, 去掉了 #define MODULE, 自动定义

static int hello_init(void)

{

printk(KERN_ALERT "Hello, world\n");

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye, cruel world\n");

}

module_init(hello_init);// 必须!!

module_exit(hello_exit); // 必须!!

注意,在 2.4 中 module_init 不是必须的,只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module

编译生成:

2.4

gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c

2.6

makefile 中要有 obj-m:= hello.o

然后:

make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules (当然简单的 make 也可以)

哈哈够简单!!

其他不同:

计数器:

以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如:

void

inc_mod(void)

{

MOD_INC_USE_COUNT;

} /* end inc_mod */

/************************************************************************

* Calculator DEC

************************************************************************/

void

dec_mod(void)

{

MOD_DEC_USE_COUNT;

} /* end dec_mod */

现在这个也过时了 !!

2.6 ,用户函数要加载模块,使用:

int try_module_get(&module);

函数卸载模块使用

module_put()

而驱动中不必显示定义 inc 和 dec

没有 kdev_t 了

现在都流行用 dev_t 了 , 而且是 32 位的

结构体初始化

老版本使用:

static struct some_structure = {

field1: value,

field2: value

};

现在流行用:

static struct some_structure = {

.field1 = value,

.field2 = value,

...

};

malloc.h

要用核态内存?用 好了,

内存池

内存管理变化不大,添加了memory pool*(#include

)。(现在什么都是pool,内存 线程

....)这是为块设备提供的,使用mempool最大的优点是分配内存不会错,也不会等待(怎么这个也和RTEMS学)。对于embed的设备还是有些

用处的。标准调用方式:

mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);

使用mempool的函数 :

mempool_alloc_t / mempool_free_t

mempool_alloc_slab / mempool_free_slab

mempool_alloc / mempool_free

mempool_resize

结构体赋值

以前,驱动中结构体赋值使用:

static struct some_structure = {

field1: value,

field2: value

};

现在要用:

static struct some_structure = {

.field1 = value,

.field2 = value,

...

};

例如 :

static struct file_operations yourdev_file_ops = {

.open = yourdev_open,

.read = yourdev_read_file,

.write = yourdev_write_file,

};

min() , max()

不少程序员定义自己的 min 和 max 宏,大家也知道宏不安全, Linux 定义了 min 和 max 函数(注意不是模板函数,需要自己制定比较类型!)

原型变化

call_usermodehelper()

request_module()

函数原型变化了,用到的赶快查 !!!

Devfs

唉,还没怎么用,就过时了的技术,这就是 linux 。不是我们落伍,是世界变化快

字符设备

2.6 中主从设备编号不再局限于原来的 8bit

register_chrdev() 可以升级为:

int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称

该函数的动态版本(不知道主设备号时使用)

int alloc_chrdev_region(dev_t *dev, unsigned baseminor,

unsigned count, char *name);

新的 file_operations

register_chrdev_region 没有使用 register_chrdev_region 参数,因为设备现在使用 struct cdev 来定义他在 中定义。

struct cdev {

struct kobject kobj;

struct module *owner;

struct file_operations *ops;

struct list_head list;

dev_t dev;

unsigned int count;

};

使用时首先需要分配空间: struct cdev *cdev_alloc(void);

然后对其初始化:

void cdev_init(struct cdev *cdev, struct file_operations *fops);

cdev 使用 kobject_set_name 设置名称:例如:

struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&cdev->kobj, "my_cdev%d", devnum);

此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。

删除 cdev 使用

void cdev_del(struct cdev *cdev);

对于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&cdev->kobj); 删除

也就是使用: struct kobject *cdev_get(struct cdev *cdev); void

cdev_put(struct cdev *cdev);

太极链;

struct inode -> i_cdev -> cdev

这样就从 inode 链接到 cdev

驱动体系:

/dev 到 /sys

/dev 也过时了,设备文件都跑到 /sys 里了!

# cd /sys

# ls

block bus class devices firmware kernel module power

3b3a60d99ba53cf09cef0f87a4834a4d.gif

知到了2.6内核的好处,很想在以后的开发中用2.6内核。但是不知道从2.4到2.6驱动的变化有多大,驱动是不是要自己一个个改?

我初学只能写些简单的驱动,或参考别人的驱动来开发。这种情况用2.6内核搞驱动是不是难度很大?

希望做过驱动移植的高手关照。

你可能感兴趣的:(linux2.6,添加驱动)