Linux26内核驱动移植参考.docx

上传人:b****3 文档编号:26494041 上传时间:2023-06-20 格式:DOCX 页数:12 大小:20.69KB
下载 相关 举报
Linux26内核驱动移植参考.docx_第1页
第1页 / 共12页
Linux26内核驱动移植参考.docx_第2页
第2页 / 共12页
Linux26内核驱动移植参考.docx_第3页
第3页 / 共12页
Linux26内核驱动移植参考.docx_第4页
第4页 / 共12页
Linux26内核驱动移植参考.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

Linux26内核驱动移植参考.docx

《Linux26内核驱动移植参考.docx》由会员分享,可在线阅读,更多相关《Linux26内核驱动移植参考.docx(12页珍藏版)》请在冰豆网上搜索。

Linux26内核驱动移植参考.docx

Linux26内核驱动移植参考

随着Linux2.6的发布,由于2.6内核做了教的改动,各个设备的驱动程序在不同程度上要

进行改写。

为了方便各位Linux爱好者我把自己整理的这分文档share出来。

该文当列举

了2.6内核同以前版本的绝大多数变化,可惜的是由于时间和精力有限没有详细列出各个

函数的用法。

特别声明:

该文档中的内容来自http:

/,该网也上也有各个函数的较为详细的

说明可供各位参考。

如果需要该文档的word版的朋友,请mail到weiriver@索

取。

1、使用新的入口

必须包含

module_init(your_init_func);

module_exit(your_exit_func);

老版本:

intinit_module(void);

voidcleanup_module(voi);

2.4中两种都可以用,对如后面的入口函数不必要显示包含任何头文件。

2、GPL

MODULE_LICENSE("DualBSD/GPL");

老版本:

MODULE_LICENSE("GPL");

3、模块参数

必须显式包含

module_param(name,type,perm);

module_param_named(name,value,type,perm);

参数定义

module_param_string(name,string,len,perm);

module_param_array(name,type,num,perm);

老版本:

MODULE_PARM(variable,type);

MODULE_PARM_DESC(variable,type);

4、模块别名

MODULE_ALIAS("alias-name");

这是新增的,在老版本中需在/etc/modules.conf配置,现在在代码中就可以实现。

5、模块计数

inttry_module_get(&module);

module_put();

老版本:

MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT

6、符号导出

只有显示的导出符号才能被其他模块使用,默认不导出所有的符号,不必使用EXPORT_NO

_SYMBOLS

老板本:

默认导出所有的符号,除非使用EXPORT_NO_SYMBOLS

7、内核版本检查

需要在多个文件中包含时,不必定义__NO_VERSION__

老版本:

在多个文件中包含时,除在主文件外的其他文件中必须定义_

_NO_VERSION__,防止版本重复定义。

8、设备号

kdev_t被废除不可用,新的dev_t拓展到了32位,12位主设备号,20位次设备号。

unsignedintiminor(structinode*inode);

unsignedintimajor(structinode*inode);

老版本:

8位主设备号,8位次设备号

intMAJOR(kdev_tdev);

intMINOR(kdev_tdev);

9、内存分配头文件变更

所有的内存分配函数包含在头文件,而原来的不存在

老版本:

内存分配函数包含在头文件

10、结构体的初试化

gcc开始采用ANSIC的struct结构体的初始化形式:

staticstructsome_structure={

.field1=value,

.field2=value,

..

};

老版本:

非标准的初试化形式

staticstructsome_structure={

field1:

value,

field2:

value,

..

};

11、用户模式帮助器

intcall_usermodehelper(char*path,char**argv,char**envp,

intwait);

新增wait参数

12、request_module()

request_module("foo-device-%d",number);

老版本:

charmodule_name[32];

printf(module_name,"foo-device-%d",number);

request_module(module_name);

13、dev_t引发的字符设备的变化

1、取主次设备号为

unsignediminor(structinode*inode);

unsignedimajor(structinode*inode);

2、老的register_chrdev()用法没变,保持向后兼容,但不能访问设备号大于256的设备

3、新的接口为

a)注册字符设备范围

intregister_chrdev_region(dev_tfrom,unsignedcount,char*name);

b)动态申请主设备号

intalloc_chrdev_region(dev_t*dev,unsignedbaseminor,unsignedcount,char

*name);

看了这两个函数郁闷吧^_^!

怎么和file_operations结构联系起来啊?

别急!

c)包含,利用structcdev和file_operations连接

structcdev*cdev_alloc(void);

voidcdev_init(structcdev*cdev,structfile_operations*fops);

intcdev_add(structcdev*cdev,dev_tdev,unsignedcount);

(分别为,申请cdev结构,和fops连接,将设备加入到系统中!

好复杂啊!

d)voidcdev_del(structcdev*cdev);

只有在cdev_add执行成功才可运行。

e)辅助函数

kobject_put(&cdev->kobj);

structkobject*cdev_get(structcdev*cdev);

voidcdev_put(structcdev*cdev);

这一部分变化和新增的/sys/dev有一定的关联。

14、新增对/proc的访问操作

以前的/proc中只能得到string,seq_file操作能得到如long等多种数据。

相关函数:

staticstructseq_operations必须实现这个类似file_operations得数据中得各个成

员函数。

seq_printf();

intseq_putc(structseq_file*m,charc);

intseq_puts(structseq_file*m,constchar*s);

intseq_escape(structseq_file*m,constchar*s,constchar*esc);

intseq_path(structseq_file*m,structvfsmount*mnt,

structdentry*dentry,char*esc);

seq_open(file,&ct_seq_ops);

等等

15、底层内存分配

1、头文件改为

2、分配标志GFP_BUFFER被取消,取而代之的是GFP_NOIO和GFP_NOFS

3、新增__GFP_REPEAT,__GFP_NOFAIL,__GFP_NORETRY分配标志

4、页面分配函数alloc_pages(),get_free_page()被包含在

5、对NUMA系统新增了几个函数:

a)structpage*alloc_pages_node(intnode_id,

unsignedintgfp_mask,

unsignedintorder);

b)voidfree_hot_page(structpage*page);

c)voidfree_cold_page(structpage*page);

6、新增Memorypools

mempool_t*mempool_create(intmin_nr,

mempool_alloc_t*alloc_fn,

mempool_free_t*free_fn,

void*pool_data);

void*mempool_alloc(mempool_t*pool,intgfp_mask);

voidmempool_free(void*element,mempool_t*pool);

intmempool_resize(mempool_t*pool,intnew_min_nr,intgfp_mask);

16、per-CPU变量

get_cpu_var();

put_cpu_var();

void*alloc_percpu(type);

voidfree_percpu(constvoid*);

per_cpu_ptr(void*ptr,intcpu)

get_cpu_ptr(ptr)

put_cpu_ptr(ptr)

老版本使用

DEFINE_PER_CPU(type,name);

EXPORT_PER_CPU_SYMBOL(name);

EXPORT_PER_CPU_SYMBOL_GPL(name);

DECLARE_PER_CPU(type,name);

DEFINE_PER_CPU(int,mypcint);

2.6内核采用了可剥夺得调度方式这些宏都不安全。

17、内核时间变化

1、现在的各个平台的HZ为

Alpha:

1024/1200;ARM:

100/128/200/1000;CRIS:

100;i386:

1000;IA-64:

1024;M68K:

100;M68K-nommu:

50-1000;MIPS:

100/128/1000;MIPS64:

100;

PA-RISC:

100/1000;PowerPC32:

100;PowerPC64:

1000;S/390:

100;SPARC32:

100;SPARC64:

100;SuperH:

100/1000;UML:

100;v850:

24-100;x86-64:

1000.

2、由于HZ的变化,原来的jiffies计数器很快就溢出了,引入了新的计数器jiffies_64

3、#include

u64my_time=get_jiffies_64();

4、新的时间结构增加了纳秒成员变量

structtimespeccurrent_kernel_time(void);

5、他的timer函数没变,新增

voidadd_timer_on(structtimer_list*timer,intcpu);

6、新增纳秒级延时函数

ndelay();

7、POSIXclocks参考kernel/posix-timers.c

18、工作队列(workqueue)

1、任务队列(taskqueue)接口函数都被取消,新增了workqueue接口函数

structworkqueue_struct*create_workqueue(constchar*name);

DECLARE_WORK(name,void(*function)(void*),void*data);

INIT_WORK(structwork_struct*work,

void(*function)(void*),void*data);

PREPARE_WORK(structwork_struct*work,

void(*function)(void*),void*data);

2、申明structwork_struct结构

intqueue_work(structworkqueue_struct*queue,

structwork_struct*work);

intqueue_delayed_work(structworkqueue_struct*queue,

structwork_struct*work,

unsignedlongdelay);

intcancel_delayed_work(structwork_struct*work);

voidflush_workqueue(structworkqueue_struct*queue);

voiddestroy_workqueue(structworkqueue_struct*queue);

intschedule_work(structwork_struct*work);

intschedule_delayed_work(structwork_struct*work,unsignedlong

delay);

19、新增创建VFS的"libfs"

libfs给创建一个新的文件系统提供了大量的API.

主要是对structfile_system_type的实现。

参考源代码:

drivers/hotplug/pci_hotplug_core.c

drivers/usb/core/inode.c

drivers/oprofile/oprofilefs.c

fs/ramfs/inode.c

fs/nfsd/nfsctl.c(simple_fill_super()example)

20、DMA的变化

未变化的有:

void*pci_alloc_consistent(structpci_dev*dev,size_tsize,

dma_addr_t*dma_handle);

voidpci_free_consistent(structpci_dev*dev,size_tsize,

void*cpu_addr,dma_addr_tdma_handle);

变化的有:

1、void*dma_alloc_coherent(structdevice*dev,size_tsize,

dma_addr_t*dma_handle,intflag);

voiddma_free_coherent(structdevice*dev,size_tsize,

void*cpu_addr,dma_addr_tdma_handle);

2、列举了映射方向:

enumdma_data_direction{

DMA_BIDIRECTIONAL=0,

DMA_TO_DEVICE=1,

DMA_FROM_DEVICE=2,

DMA_NONE=3,

};

3、单映射

dma_addr_tdma_map_single(structdevice*dev,void*addr,

size_tsize,

enumdma_data_directiondirection);

voiddma_unmap_single(structdevice*dev,dma_addr_tdma_addr,

size_tsize,

enumdma_data_directiondirection);

4、页面映射

dma_addr_tdma_map_page(structdevice*dev,structpage*page,

unsignedlongoffset,size_tsize,

enumdma_data_directiondirection);

voiddma_unmap_page(structdevice*dev,dma_addr_tdma_addr,

size_tsize,

enumdma_data_directiondirection);

5、有关scatter/gather的函数:

intdma_map_sg(structdevice*dev,structscatterlist*sg,

intnents,enumdma_data_directiondirection);

voiddma_unmap_sg(structdevice*dev,structscatterlist*sg,

intnhwentries,enumdma_data_directiondirection);

6、非一致性映射(NoncoherentDMAmappings)

void*dma_alloc_noncoherent(structdevice*dev,size_tsize,

dma_addr_t*dma_handle,intflag);

voiddma_sync_single_range(structdevice*dev,dma_addr_tdma_handle,

unsignedlongoffset,size_tsize,

enumdma_data_directiondirection);

voiddma_free_noncoherent(structdevice*dev,size_tsize,

void*cpu_addr,dma_addr_tdma_handle);

7、DAC(doubleaddresscycle)

intpci_dac_set_dma_mask(structpci_dev*dev,u64mask);

voidpci_dac_dma_sync_single(structpci_dev*dev,

dma64_addr_tdma_addr,

size_tlen,intdirection);

21、互斥

新增seqlock主要用于:

1、少量的数据保护

2、数据比较简单(没有指针),并且使用频率很高

3、对不产生任何副作用的数据的访问

4、访问时写者不被饿死

初始化

seqlock_tlock1=SEQLOCK_UNLOCKED;

或seqlock_tlock2;seqlock_init(&lock2);

voidwrite_seqlock(seqlock_t*sl);

voidwrite_sequnlock(seqlock_t*sl);

intwrite_tryseqlock(seqlock_t*sl);

voidwrite_seqlock_irqsave(seqlock_t*sl,longflags);

voidwrite_sequnlock_irqrestore(seqlock_t*sl,longflags);

voidwrite_seqlock_irq(seqlock_t*sl);

voidwrite_sequnlock_irq(seqlock_t*sl);

voidwrite_seqlock_bh(seqlock_t*sl);

voidwrite_sequnlock_bh(seqlock_t*sl);

unsignedintread_seqbegin(seqlock_t*sl);

intread_seqretry(seqlock_t*sl,unsignedintiv);

unsignedintread_seqbegin_irqsave(seqlock_t*sl,longflags);

intread_seqretry_irqrestore(seqlock_t*sl,unsignedintiv,long

flags);

22、内核可剥夺

preempt_disable();

preempt_enable_no_resched();

preempt_enable_noresched();

preempt_check_resched();

23、眠和唤醒

1、原来的函数可用,新增下列函数:

prepare_to_wait_exclusive();

prepare_to_wait();

2、等待队列的变化

typedefint(*wait_queue_func_t)(wait_queue_t*wait,

unsignedmode,intsync);

voidinit_waitqueue_func_entry(wait_queue_t*queue,

wait_queue_func_tfunc);

24、新增完成事件(completionevents)

init_completion(&my_comp);

voidwait_for_completion(structcompletion*comp);

voidcomplete(structcompletion*comp);

voidcomplete_all(structcompletion*comp);

25、RCU(Read-copy-update)

rcu_read_lock();

voidcall_rcu(structrcu_head*head,void(*func)(void*arg),

void*arg);

26、中断处理

1、中断处理有返回值了。

IRQ_RETVAL(handled);

2、cli(),sti(),save_flags(),和restore_flags()不再有效,应该使用local_save

_flags()或local_irq_disable()。

3、synchronize

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1