




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
驱动入门知识设备驱动简介:内核功能划分:1、 进程管理进程管理功能负责创建销毁进程,并处理他们与外界之间的连接(输入输出)。不同进程之间的通信是整个系统的基本功能。2、 内存管理内核在有限的可用资源之上为每个进程都创建了一个虚拟的得知空间,内核的不同部分在和内存管理子系统法交互的时候使用一组函数调用,包括简单的malloc/free函数3、 文件系统Unix中的每个对象几乎都可以当作文件来看待。内核在没有结构的硬件上构造结构化的文件系统4、 设备控制几乎每一个系统操作最终都会映射到物理设备上。除了处理器、内存以及其他很有限的几个对象外,所有设备操作都由相关的代码来完成,这段代码就叫做驱动程序内核必须为系统中的每件外设嵌入相应的驱动程序5、 网络功能大部分网络操作和具体的进程无关,数据包的传入是异步事件。在某个进程处理这些数据包之前,必须收集标识和分发这些数据包系统负责在应用程序和网络接口之间传递数据包。设备和模块的分类:字符设备:块设备:网络接口:模块:首先是模块,内核的驱动分为两种形式,一种是直接编译进内核,另一种是写成模块,这样在需要的时候可以装载,不需要的时候就可以接卸,所以要了解驱动首先从模块入手。在我们学习编程的时候,第一个写的程序基本上都是hello_word。所以,我们现在也写一个hello_word模块。//Hello_word.c#include<linux/init.h>#include<linux/kernel.h>#include<linux/module.h>staticinthello_init(void){printk(KERN_ALERT"Moduleinit:Helloword!\n");return0;}staticvoidhello_exit(void){printk(KERN_ALERT"Moduleexit:bye-bye\n");return;}module_init(hello_init);module_exit(hello_exit);对应的用来编译hello_word的makefile文件//Makefileobj-m:=hw_module.ohw_modulemodule-objs:=moduleKDIR:=/lib/modules/3.5.0-57-generic/buildMAKE:=makedefault:$(MAKE)-C$(KDIR)SUBDIRS=$(PWD)modulesclean:$(MAKE)-C$(KDIR)SUBDIRS=$(PWD)clean这样一个简单的模块就完成了,这里的程序写法、调用与用户空间的程序有很多不同。比如,模块函数没有main函数,在装载模块的时候会调用module_init(hello_init);注册函数,这里注册的是hello_init。在模块卸载时候同样会调用module_exit(hello_exit);注册函数,这里注册的是hello_exit。module_init注册函数主要是初始化,分配内存,注册设备等等,而module_exit中注册函数恰恰相反,主要是释放内存,注销设备等等。还有在内河中用printk打印信息,不过printk不支持浮点型数据,printk中可以加入7种信息级别#defineKERN_EMERG"<0>"/*systemisunusable*/#defineKERN_ALERT"<1>"/*actionmustbetakenimmediately*/#defineKERN_CRIT"<2>"/*criticalconditions*/#defineKERN_ERR"<3>"/*errorconditions*/#defineKERN_WARNING"<4>"/*warningconditions*/#defineKERN_NOTICE"<5>"/*normalbutsignificant*/#defineKERN_INFO"<6>"/*informational*/#defineKERN_DEBUG"<7>"/*debug-levelmessages*/对应与不同用户的错误等级选择不同的option,并做不同的处理,小于一定等级的信息答应到终端可以使用dmesg来查看全部的打印信息。编译内核的头文件是在/lib/modules/$(shelluname-r)/build/include/目录下的,而不是用户目录下/usr/include/,所以编译后不会产生可执行文件,而是一个.ko的文件。下来就是加载/卸载模块。加载模块命令:insmodxxx.ko卸载模块命令:rmmodxxx.ko查看模块命令:lsmod简单的字符设备驱动:1、 主次设备号2、 字符设备中重要的数据结构文件操作File结构3.Inode结构4.Cdev结构3、 字符设备的注册Platform总线架构:从Linux2.6内核起,引入一套新的驱动管理注册机制:platform_device和platform_driver。Linux中大部分的设备驱动都可以使用这套机制,设备用platform_device表示,设备用platform_driver进行注册。Linuxplatformdriver机制和传统的device机制(通过driver_register函数进行注册)相比有一个十分明显的优势,那就是platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时,通过platformdevice提供的标准接口进行申请并使用。Platform是一个虚拟的地址总线,相比PCI、USB,他主要用于描述SOC上的资源。Platform所描述的资源有一个共同点:在CPU的总线上直接取址。Platform总线下驱动开发步骤:1、 设备设备注册中,需要实现的机构体是:platform_device初始化resource结构变量初始化platform_device结构变量向系统注册设备:platform_device_registero以上三步必须在设备驱动加载前完成。2、 驱动驱动注册中,需要实现的结构体是:platform_driver。在驱动程序的初始化函数中,调用了platform_driver_register()注册platform_driver。这里需要注意的是platform_driver和platform_device中的name变量的值必须是相同的。因为,在platform_driver_register()注册时会将当前注册的platform_driver中的name变量的值和已注册的所有platform_device中的name变量的值进行比较,只有找到具有相同名称的platform_device才能注册成功。当注册成功时,会调用platform_driver结构元素probe函数指针进入CF卡驱动的入口函数是phoenix_ide_init()函数,进去之后发现里面就一句话voidphoenix_ide_init(void){platform_driver_register(&nlm_common_ide_driver);}再进入platform_driver_register()函数看看intplatform_driver_register(structplatform_driver*drv){drv->driver.bus=&platform_bus_type;if(drv->probe)drv->be=platform_drv_probe;if(drv->remove)drv->driver.remove=platform_drv_remove;if(drv->shutdown)drv->driver.shutdown=platform_drv_shutdown;if(drv->suspend)drv->driver.suspend=platform_drv_suspend;if(drv->resume)drv->driver.resume=platform_drv_resume;if(drv->pm)drv->driver.pm=&drv->pm->base;returndriver_register(&drv->driver);}在这个函数中对drv结构体进行了赋值,最后调用dirver_register注册dirver成员,在赋值的过程中调用了probe函数指针,下面看看probe函数staticstructplatform_drivernlm_common_ide_driver={.driver={.name = "xlp-ide-commpact",.owner = THIS_MODULE,.of_match_table=nlm_common_ide_dt_ids,},.probe =nlm_drv_ide_probe,.remove =nlm_common_ide_remove,};staticint__devinitnlm_drv_ide_probe(structplatform_device*dev){unsignedinti=0;intret=0;structide_host*host;unsignedlongaddr;structide_hwhw,*hws[]={&hw};
ide_hwif_t*nlm_common_ide_hwif;u32l2_irq;printk("InitializingxlrPCMCIAIDE...\n");memset(&hw,0,sizeof(hw));addr=(unsignedlong)get_localbus_add(CS_CF);printk(KERN_ALERT"DEBUG__ADDR=%x...\n”,addr);if(addr==INVALID_U32){printk("localbushavenotassignmemoryforcf\r\n");return-1;}hw.io_ports.data_addrhw.io_ports.error_addrhw.io_ports.nsect_addrhw.io_ports.lbal_addrhw.io_ports.lbam_addrhw.io_ports.lbah_addrhw.io_ports.device_addrhw.io_ports.status_addrhw.io_ports.ctl_addrhw.io_ports.irq_addrhw.io_ports.data_addrhw.io_ports.error_addrhw.io_ports.nsect_addrhw.io_ports.lbal_addrhw.io_ports.lbam_addrhw.io_ports.lbah_addrhw.io_ports.device_addrhw.io_ports.status_addrhw.io_ports.ctl_addrhw.io_ports.irq_addr=NETLOGIC_IDE_REG(addr,0x82);=NETLOGIC_IDE_REG(addr,0x84);=NETLOGIC_IDE_REG(addr,0x86);=NETLOGIC_IDE_REG(addr,0x88);=NETLOGIC_IDE_REG(addr,0x8a);=NETLOGIC_IDE_REG(addr,0x8c);=NETLOGIC_IDE_REG(addr,0x8e);=NETLOGIC_IDE_REG(addr,0x4c);=NETLOGIC_IDE_REG(addr,0x4e);hw.dev=&dev->dev;〃中断初始化l2_irq=bsp_get_irq_num(DRV_IRQ_CF0);hw.irq=l2_irq;request_l2_irq_register(l2_int_connect);/*注册cfreset函数*/l2_int_connect(hw.irq,cf_default_int_proc,(void*)0);int_enable(hw.irq);ret=ide_host_add(&nlm_common_port_info,hws,1,&host);if(ret)gotoout;platform_set_drvdata(dev,host);nlm_common_ide_hwif=host->ports[0];printk("NetlogicXLRPCMCIAconfiguredasIDEinterface=%d\n",i);u32test=1;u8*pstr=(u8*)&test;if(*pstr==1)printk("DEBUG__Little_endian.....\n"); //Little_endianelseprintk("DEBUG__Big_endian \n");//Big_endianout:returnret;}在这里先看蓝色标记的代码(之前的是一些初始化赋值)ret=ide_host_add(&nlm_common_port_info,hws,1,&host);Ide_host_add函数在内核t_all/tos/drivers/ide/ide_probe.c文件中,源代码如下:intide_host_add(conststructide_port_info*d,structide_hw**hws,unsignedintn_ports,structide_host**hostp){structide_host*host;intrc;1516host=ide_host_alloc(d,hws,n_ports);if(host==NULL)return-ENOMEM;1520rc=ide_host_register(host,d,hws);if(rc){ide_host_free(host);returnrc;}1526if(hostp)*hostp=host;1529return0;}EXPORT_SYMBOL_GPL(ide_host_add);在该函数中先是用ide_host_alloc函数给**hws分配内存并初始化,再用函数ide_host_register注册到内核中。intide_host_register(structide_host*host,conststructide_port_info*d,structide_hw**hws){ide_hwif_t*hwif,*mate=NULL;inti,j=0;
14201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463ide_host_for_each_port(i,hwif,host){if(hwif==NULL){mate=NULL;continue;}ide_init_port_hw(hwif,hws[i]);ide_port_apply_params(hwif);if((i&1)&&mate){hwif->mate=mate;mate->mate=hwif;}mate=(i&1)?NULL:hwif;ide_init_port(hwif,i&1,d);ide_port_cable_detect(hwif);hwif->port_flags|=IDE_PFLAG_PROBING;ide_port_init_devices(hwif);}ide_host_for_each_port(i,hwif,host){if(hwif==NULL)continue;if(ide_probe_port(hwif)==0)hwif->present=1;hwif->port_flags&=~IDE_PFLAG_PROBING;if((hwif->host_flags&IDE_HFLAG_4DRIVES)==0||hwif->mate==NULL||hwif->mate->present==0){if(ide_register_port(hwif)){ide_disable_port(hwif);continue;}}if(hwif->present)ide_port_tune_devices(hwif);
146414651466146714681469147014711472147314741475147614771478147
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 海南大学《插画基础》2023-2024学年第二学期期末试卷
- 波束赋形技术研究-第1篇-洞察及研究
- 政治品德考核题目及答案
- 柔性电池能量管理策略-洞察及研究
- 招投标安全试题及答案
- 债权投资题库及答案详解
- 医院感染管理基本要求
- 贵阳学院《类型电影创作》2023-2024学年第二学期期末试卷
- 预备年级考试试题及答案
- 湖北大学《竞技竞赛》2023-2024学年第二学期期末试卷
- 食品标准操作规程
- 青海大学《普通化学》2022-2023学年第一学期期末试卷
- 浙江省杭州市2023-2024学年高一下学期期末教学质量检测政治试题
- 电网工程劳务分包投标方案(技术方案)
- 国开(山东)2024年《小学生心理健康教育》形考1-3终考答案
- 《积极心理学(第3版)》 课件 第10章 感恩
- 人工智能营销(第2版)课件全套 阳翼 第1-8章 迈入人工智能领域-人工智能营销的伦理与法律问题
- 人音版四下第5课 陕北绿了百姓笑了
- 2024年重庆市两江新区数学五下期末复习检测试题含解析
- 大学生心理健康教育智慧树知到期末考试答案章节答案2024年湖南中医药大学
- 江苏省南通市2022-2023学年五年级下学期数学期末试卷(含答案)2
评论
0/150
提交评论