Linux26版本内核下驱动程序移植参考Word格式文档下载.docx
《Linux26版本内核下驱动程序移植参考Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Linux26版本内核下驱动程序移植参考Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
linux/moduleparam.h>
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
http:
//www.fsl.cs.sunysb.edu/~sean/parser.cgi?
modules
In2.4modules,theMOD_INC_USE_COUNTmacroisusedtopreventunloadingofthemodulewhilethereisanopenfile.The2.6kernel,however,knowsnottounloadamodulethatownsacharacterdevicethat'
scurrentlyopen.
However,thisrequiresthatthemodulebeexplicitinspecifyingownershipofcharacterdevices,usingtheTHIS_MODULEmacro.YoualsohavetotakeoutallcallstoMOD_INC_USE_COUNTandMOD_DEC_USE_COUNT.
staticstructfile_operationsfops=
{
.owner=THIS_MODULE,
.read=device_read,
.write=device_write,
.open=device_open,
.release=device_release
}
The2.6kernelconsidersmodulesthatusethedeprecatedfacilitytobeunsafe,anddoesnotpermittheirunloading,evenwithrmmod-f.
2.6,2.5的kbuild不需要到处加上MOD_INC_USE_COUNT来消除模块卸载竞争(moduleunloadrace)
6、符号导出
只有显示的导出符号才能被其他模块使用,默认不导出所有的符号,不必使用EXPORT_NO
_SYMBOLS
老板本:
默认导出所有的符号,除非使用EXPORT_NO_SYMBOLS
7、内核版本检查
需要在多个文件中包含<
linux/module.h>
时,不必定义__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、内存分配头文件变更
所有的内存分配函数包含在头文件<
linux/slab.h>
,而原来的<
linux/malloc.h>
不存在
内存分配函数包含在头文件<
10、结构体的初试化
gcc开始采用ANSIC的struct结构体的初始化形式:
staticstructsome_structure={
.field1=value,
.field2=value,
..
};
非标准的初试化形式
field1:
value,
field2:
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,"
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)包含<
linux/cdev.h>
,利用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的访问操作
<
linux/seq_file.h>
以前的/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()被包含在<
linux/gfp.h>
中
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
linux/mempool.h>
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:
M68K-nommu:
50-1000;
MIPS:
100/128/1000;
MIPS64:
PA-RISC:
100/1000;
PowerPC32:
PowerPC64:
S/390:
SPARC32:
100;
SPARC64:
SuperH:
UML:
v850:
24-100;
x86-64:
1000.
2、由于HZ的变化,原来的jiffies计数器很快就溢出了,引入了新的计数器jiffies_64
3、#include<
linux/jiffies.h>
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,
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,
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,
4、页面映射
dma_addr_tdma_map_page(structdevice*dev,structpage*page,
unsignedlongoffset,size_tsize,
voiddma_unmap_page(structdevice*dev,dma_addr_tdma_addr,
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,
voiddma_sync_single_range(structdevice*dev,dma_addr_tdma_handle,
voiddma_free_noncoherent(structdevice*dev,size_tsize,
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、访问时写者不被饿死
linux/seqlock.h>
初始化
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