Linux 驅動設計?從2.4到2.6

admin @ 2014-03-25 , reply:0

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




[admin via 研發互助社區 ] Linux 驅動設計?從2.4到2.6已經有1209次圍觀

http://cocdig.com/docs/show-post-42473.html