Linux2.6 驱动设计――从 2.4 到 2.6
2012-10-31 09:26
573 查看
[align=left]Linux2.6 驱动设计――从 2.4 到 2.6[/align]
RTEMS版权所有,转载请注明来源www.rtems.net,作者ray@rtems
[align=left]Linux 2.6 和 2.4 的比较我不想废话,总体来说 2.6 功能更强,但是资源消耗更多。[/align]
[align=left]由于 2.6 内核在驱动框架,底层调用上和 2.4 内核有很多差别,所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。[/align]
[align=left]2.6 和 2.4 主要的不同在于[/align]
[align=left]? 内核的 API 变化,增加了不少新功能(例如 mem pool )[/align]
[align=left]? 提供 sysfs 用于描述设备树[/align]
[align=left]? 驱动模块从 .o 变为 .ko[/align]
移植 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");
}
[align=left]2.6的hello world版本![/align]
#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); // 必须!!
[align=left]注意,在 2.4 中 module_init 不是必须的,只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module[/align]
编译生成:
2.4
[align=left]gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c[/align]
[align=left]2.6[/align]
[align=left]makefile 中要有 obj-m:= hello.o[/align]
[align=left]然后:[/align]
[align=left]make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules (当然简单的 make 也可以)[/align]
[align=left]哈哈够简单!![/align]
其他不同:
计数器:
以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如:
[align=left]void[/align]
[align=left]inc_mod(void)[/align]
[align=left]{[/align]
[align=left]MOD_INC_USE_COUNT;[/align]
[align=left]} /* end inc_mod */[/align]
/************************************************************************
[align=left]* Calculator DEC[/align]
[align=left]************************************************************************/[/align]
[align=left]void[/align]
[align=left]dec_mod(void)[/align]
[align=left]{[/align]
[align=left]MOD_DEC_USE_COUNT;[/align]
[align=left]} /* end dec_mod */[/align]
[align=left]现在这个也过时了 !![/align]
[align=left]2.6 ,用户函数要加载模块,使用:[/align]
[align=left]int try_module_get(&module);[/align]
[align=left]函数卸载模块使用[/align]
[align=left]module_put()[/align]
[align=left]而驱动中不必显示定义 inc 和 dec[/align]
没有 kdev_t 了
现在都流行用 dev_t 了 , 而且是 32 位的
结构体初始化
老版本使用:
[align=left]static struct some_structure = {[/align]
[align=left]field1: value,[/align]
[align=left]field2: value[/align]
[align=left]};[/align]
[align=left]现在流行用:[/align]
[align=left]static struct some_structure = {[/align]
[align=left].field1 = value,[/align]
[align=left].field2 = value,[/align]
[align=left]...[/align]
[align=left]};[/align]
malloc.h
要用核态内存?用 <linux/slab.h> 好了,
内存池
内存管理变化不大,添加了memory pool*(#include<linux/mempool.h> )。(现在什么都是pool,内存 线程 ....)这是为块设备提供的,使用mempool最大的优点是分配内存不会错,也不会等待(怎么这个也和RTEMS学)。对于embed的设备还是有些用处的。标准调用方式:
[align=left]mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);[/align]
[align=left]使用mempool的函数 :[/align]
[align=left]mempool_alloc_t / mempool_free_t[/align]
[align=left]mempool_alloc_slab / mempool_free_slab[/align]
[align=left]mempool_alloc / mempool_free[/align]
[align=left]mempool_resize[/align]
[align=left] [/align]
结构体赋值
以前,驱动中结构体赋值使用:
[align=left]static struct some_structure = {[/align]
[align=left]field1: value,[/align]
[align=left]field2: value[/align]
[align=left]};[/align]
现在要用:
[align=left]static struct some_structure = {[/align]
[align=left].field1 = value,[/align]
[align=left].field2 = value,[/align]
[align=left]...[/align]
[align=left]};[/align]
[align=left]例如 :[/align]
[align=left]static struct file_operations yourdev_file_ops = {[/align]
[align=left].open = yourdev_open,[/align]
[align=left].read = yourdev_read_file,[/align]
[align=left].write = yourdev_write_file,[/align]
[align=left]};[/align]
min() , max()
不少程序员定义自己的 min 和 max 宏,大家也知道宏不安全, Linux 定义了 min 和 max 函数(注意不是模板函数,需要自己制定比较类型!)
原型变化
call_usermodehelper()
[align=left]request_module()[/align]
[align=left]函数原型变化了,用到的赶快查 !!![/align]
Devfs
唉,还没怎么用,就过时了的技术,这就是 linux 。不是我们落伍,是世界变化快
字符设备
2.6 中主从设备编号不再局限于原来的 8bit
[align=left]register_chrdev() 可以升级为:[/align]
[align=left]int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称[/align]
[align=left]该函数的动态版本(不知道主设备号时使用)[/align]
[align=left]int alloc_chrdev_region(dev_t *dev, unsigned baseminor,[/align]
[align=left]unsigned count, char *name);[/align]
新的 file_operations
register_chrdev_region 没有使用 register_chrdev_region 参数,因为设备现在使用 struct cdev 来定义他在 <linux/cdev.h> 中定义。
[align=left]struct cdev {[/align]
[align=left]struct kobject kobj;[/align]
[align=left]struct module *owner;[/align]
[align=left]struct file_operations *ops;[/align]
[align=left]struct list_head list;[/align]
[align=left]dev_t dev;[/align]
[align=left]unsigned int count;[/align]
[align=left]};[/align]
[align=left]使用时首先需要分配空间: struct cdev *cdev_alloc(void);[/align]
[align=left]然后对其初始化:[/align]
[align=left]void cdev_init(struct cdev *cdev, struct file_operations *fops);[/align]
[align=left]cdev 使用 kobject_set_name 设置名称:例如:[/align]
[align=left]struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&cdev->kobj, "my_cdev%d", devnum);[/align]
[align=left]此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。[/align]
[align=left]删除 cdev 使用[/align]
[align=left]void cdev_del(struct cdev *cdev);[/align]
[align=left]对于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&cdev->kobj); 删除 也就是使用: struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev); [/align]
太极链;
struct inode -> i_cdev -> cdev
[align=left]这样就从 inode 链接到 cdev[/align]
驱动体系:
/dev 到 /sys
[align=left]/dev 也过时了,设备文件都跑到 /sys 里了![/align]
[align=left]# cd /sys[/align]
[align=left]# ls[/align]
[align=left]block bus class devices firmware kernel module power[/align]
[align=left]哈哈,看上去清晰多了。[/align]
[align=left]Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=470624[/align]
RTEMS版权所有,转载请注明来源www.rtems.net,作者ray@rtems
[align=left]Linux 2.6 和 2.4 的比较我不想废话,总体来说 2.6 功能更强,但是资源消耗更多。[/align]
[align=left]由于 2.6 内核在驱动框架,底层调用上和 2.4 内核有很多差别,所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。[/align]
[align=left]2.6 和 2.4 主要的不同在于[/align]
[align=left]? 内核的 API 变化,增加了不少新功能(例如 mem pool )[/align]
[align=left]? 提供 sysfs 用于描述设备树[/align]
[align=left]? 驱动模块从 .o 变为 .ko[/align]
移植 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");
}
[align=left]2.6的hello world版本![/align]
#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); // 必须!!
[align=left]注意,在 2.4 中 module_init 不是必须的,只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module[/align]
编译生成:
2.4
[align=left]gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c[/align]
[align=left]2.6[/align]
[align=left]makefile 中要有 obj-m:= hello.o[/align]
[align=left]然后:[/align]
[align=left]make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules (当然简单的 make 也可以)[/align]
[align=left]哈哈够简单!![/align]
其他不同:
计数器:
以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如:
[align=left]void[/align]
[align=left]inc_mod(void)[/align]
[align=left]{[/align]
[align=left]MOD_INC_USE_COUNT;[/align]
[align=left]} /* end inc_mod */[/align]
/************************************************************************
[align=left]* Calculator DEC[/align]
[align=left]************************************************************************/[/align]
[align=left]void[/align]
[align=left]dec_mod(void)[/align]
[align=left]{[/align]
[align=left]MOD_DEC_USE_COUNT;[/align]
[align=left]} /* end dec_mod */[/align]
[align=left]现在这个也过时了 !![/align]
[align=left]2.6 ,用户函数要加载模块,使用:[/align]
[align=left]int try_module_get(&module);[/align]
[align=left]函数卸载模块使用[/align]
[align=left]module_put()[/align]
[align=left]而驱动中不必显示定义 inc 和 dec[/align]
没有 kdev_t 了
现在都流行用 dev_t 了 , 而且是 32 位的
结构体初始化
老版本使用:
[align=left]static struct some_structure = {[/align]
[align=left]field1: value,[/align]
[align=left]field2: value[/align]
[align=left]};[/align]
[align=left]现在流行用:[/align]
[align=left]static struct some_structure = {[/align]
[align=left].field1 = value,[/align]
[align=left].field2 = value,[/align]
[align=left]...[/align]
[align=left]};[/align]
malloc.h
要用核态内存?用 <linux/slab.h> 好了,
内存池
内存管理变化不大,添加了memory pool*(#include<linux/mempool.h> )。(现在什么都是pool,内存 线程 ....)这是为块设备提供的,使用mempool最大的优点是分配内存不会错,也不会等待(怎么这个也和RTEMS学)。对于embed的设备还是有些用处的。标准调用方式:
[align=left]mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);[/align]
[align=left]使用mempool的函数 :[/align]
[align=left]mempool_alloc_t / mempool_free_t[/align]
[align=left]mempool_alloc_slab / mempool_free_slab[/align]
[align=left]mempool_alloc / mempool_free[/align]
[align=left]mempool_resize[/align]
[align=left] [/align]
结构体赋值
以前,驱动中结构体赋值使用:
[align=left]static struct some_structure = {[/align]
[align=left]field1: value,[/align]
[align=left]field2: value[/align]
[align=left]};[/align]
现在要用:
[align=left]static struct some_structure = {[/align]
[align=left].field1 = value,[/align]
[align=left].field2 = value,[/align]
[align=left]...[/align]
[align=left]};[/align]
[align=left]例如 :[/align]
[align=left]static struct file_operations yourdev_file_ops = {[/align]
[align=left].open = yourdev_open,[/align]
[align=left].read = yourdev_read_file,[/align]
[align=left].write = yourdev_write_file,[/align]
[align=left]};[/align]
min() , max()
不少程序员定义自己的 min 和 max 宏,大家也知道宏不安全, Linux 定义了 min 和 max 函数(注意不是模板函数,需要自己制定比较类型!)
原型变化
call_usermodehelper()
[align=left]request_module()[/align]
[align=left]函数原型变化了,用到的赶快查 !!![/align]
Devfs
唉,还没怎么用,就过时了的技术,这就是 linux 。不是我们落伍,是世界变化快
字符设备
2.6 中主从设备编号不再局限于原来的 8bit
[align=left]register_chrdev() 可以升级为:[/align]
[align=left]int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称[/align]
[align=left]该函数的动态版本(不知道主设备号时使用)[/align]
[align=left]int alloc_chrdev_region(dev_t *dev, unsigned baseminor,[/align]
[align=left]unsigned count, char *name);[/align]
新的 file_operations
register_chrdev_region 没有使用 register_chrdev_region 参数,因为设备现在使用 struct cdev 来定义他在 <linux/cdev.h> 中定义。
[align=left]struct cdev {[/align]
[align=left]struct kobject kobj;[/align]
[align=left]struct module *owner;[/align]
[align=left]struct file_operations *ops;[/align]
[align=left]struct list_head list;[/align]
[align=left]dev_t dev;[/align]
[align=left]unsigned int count;[/align]
[align=left]};[/align]
[align=left]使用时首先需要分配空间: struct cdev *cdev_alloc(void);[/align]
[align=left]然后对其初始化:[/align]
[align=left]void cdev_init(struct cdev *cdev, struct file_operations *fops);[/align]
[align=left]cdev 使用 kobject_set_name 设置名称:例如:[/align]
[align=left]struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&cdev->kobj, "my_cdev%d", devnum);[/align]
[align=left]此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。[/align]
[align=left]删除 cdev 使用[/align]
[align=left]void cdev_del(struct cdev *cdev);[/align]
[align=left]对于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&cdev->kobj); 删除 也就是使用: struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev); [/align]
太极链;
struct inode -> i_cdev -> cdev
[align=left]这样就从 inode 链接到 cdev[/align]
驱动体系:
/dev 到 /sys
[align=left]/dev 也过时了,设备文件都跑到 /sys 里了![/align]
[align=left]# cd /sys[/align]
[align=left]# ls[/align]
[align=left]block bus class devices firmware kernel module power[/align]
[align=left]哈哈,看上去清晰多了。[/align]
[align=left]Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=470624[/align]
相关文章推荐
- Linux2.6 驱动设计――从 2.4 到 2.6(转)
- Linux2.6 驱动设计――从 2.4 到 2.6
- Linux2.6内核驱动与2.4的区别
- 【转载】从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- Linux2.6内核驱动与2.4的区别
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- Linux2.6内核驱动移植(与2.4模块的区别)
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- Linux 2.6 驱动设计快速入门
- Linux驱动学习——2.4与2.6的一点区别
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响(一)