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 <linux/module.h> 
#include <linux/kernel.h> 
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 
要用核态内存?用 <linux/slab.h> 好了, 

内存池 
内存管理变化不大,添加了memory pool*(#include<linux/mempool.h> )。(现在什么都是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 来定义他在 <linux/cdev.h> 中定义。 

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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值