原创 s1d13506在Linux中的驱动编写方法

2008-12-29 09:38 3326 9 10 分类: 软件与OS

        PC架构中的绝大部分设备都是通过PCI局部总线与CPU进行通信,系统上电之后需要进行PCI总线的扫描,当扫描到一个PCI设备之后,在内核会创建一个物理设备对象(PDO),如果是PCI设备,该对象类型为pci_dev,并且对该对象进行初始化,分配相应的资源,上述行为属于总线驱动的工作范畴。PDO初始化成功之后,系统会调用device_add完成设备驱动程序的加载。Device_add函数一方面会通过设备管理机制向udev守护进程发送添加设备的消息;另一方面会调用bus_add_device()函数加载设备驱动。加载设备驱动时,Linux内核会遍历相应总线上的所有驱动程序,如果能够找到匹配的驱动,那么系统会调用驱动程序所提供的probe()函数探测具体的设备。在设备驱动程序的probe()函数中可以创建具体的逻辑设备对象(FDO),并且对其进行初始化。这些工作都完成之后,一个物理设备的驱动全部加载成功,在/dev目录下就可以看到具体的设备节点了。


在嵌入式系统中一般都不会采用复杂的PCI局部总线,而是将设备直接挂接到CPU的外围扩展总线上,在At91rm9200为核心的嵌入式系统中,s1d13506作为显示控制器可以直接挂接到EBI总线上,并且分配有固定的访问地址,例如可以将CS3作为s1d13506的片选信号对其进行访问,访问空间为512MB,满足了嵌入式应用的需求。这样的硬件结构实现较为单一,不存在标准的局部总线,因此s1d13506驱动设计过程中就不会存在设备扫描、资源自动分配等工作,而是固定的将设备挂接到一个虚拟的伪总线上,生成一个PDO对象,然后再加载具体的设备驱动。下面对s1d13506驱动的实现进行说明。


Linux中的标准驱动程序类似,S1d13506驱动采用分层的设计框架,底层为总线驱动,上层为设备驱动,向外导出字符设备。


在硬件层s1d13506控制器直接挂接到了EBI总线上,在内核中该物理设备对象被挂接到一条虚拟的伪总线上,该伪总线为platform_busplatform.c为该总线的核心驱动。Platform bus不具备自动识别的功能,所以需要主动将s1d13506注册到该总线上。首先需要定义s1d13506的物理设备对象dk_s1dfb_device,该对象的具体描述如下:


struct platform_device {


       char        * name;                 /* 设备名称 */


       u32         id;                


       struct device   dev;               /* 用于设备管理的对象 */


       u32         num_resources;      /* 资源数 */


       struct resource * resource;      /* 与设备相关的资源 */


};


在系统初始化时,调用platform_device_register()函数将dk_s1dfb_device对象添加到platform bus上。在PDO中一个重要的域为resource,该域的实现需要与具体的嵌入式系统硬件相关:


static struct resource dk_s1dfb_resource[] = {


       {     /* video mem */


              .name   = "s1d13806 memory",


              .start  =  0x40200000,


              .end    =  0x40200000 + 0x200000 -1,


              .flags  = IORESOURCE_MEM,


       }, {  /* video registers */


              .name   = "s1d13806 registers",


              .start  =  0x40000000,


              .end    =  0x40000000 + 0x200000 -1,


              .flags  = IORESOURCE_MEM,


       },


};


    在platform_device_register()函数中会调用device_add()函数加载设备驱动,该过程与标准PCI设备保持一致,并且通过udev机制创建设备节点。在设备驱动中,需要定义一个device_driver对象,然后通过driver_register函数将驱动注册到platform伪总线上。设备驱动中的核心函数是probe函数,该函数完成内存地址的映射,并且创建生成framebuffer设备,该设备的对外接口通过ops函数导出。由s1d13506构成的图形设备驱动程序框架如下图所示:


0232fbd2-a415-466d-8aa0-ac16aca01247.JPG


    为了提高效率,设备驱动可以通过memap机制将s1d13506的显存空间映射到应用程序的地址空间,这样应用程序可以直接对现存空间进行操作,而无需数据的拷贝,为了达到这样的目的,在framebuffer操作层提供了fb_mmap()的接口,具体方法需要由s1d13506设备驱动提供。

文章评论1条评论)

登录后参与讨论

用户147174 2008-12-29 18:39

关注 中
相关推荐阅读
用户411565 2012-12-18 12:58
我的存储之道博客
大家好,最近一直在做存储方面的工作,所以我在51CTO上专门开辟了一个空间讨论存储相关的问题,喜欢存储的朋友可以可以访问我的存储博客: 存储之道 (http://alanwu.blog.51cto...
用户411565 2012-04-06 21:39
SAS Cable可以有多长?
SAS接口是高端硬盘的主流接口,是存储系统的理想选择。我们知道高速信号的传输距离和传输线相关的,那么SAS作为外部通信接口,其Cable线具体可以有多长呢? 我在网上找到上图所示的眼图测...
用户411565 2012-04-06 21:38
对TRIM SCSI命令的一些分析
前一段时间做了一些对SSD方面进行优化的工作,SSD最大的问题在于长时间使用之后,IO性能会急剧下降。其主要问题在于为了防止“写放大”问题的产生,SSD的firmware采用了类似于log方式的算...
用户411565 2012-04-06 21:35
惊叹!我们的跨洋网络
  每次地质自然灾害的时候,总会伴随着网络的问题,这是由于我们的越洋光纤网络出了故障,受到自然力的破坏而导致断裂。越洋光纤,听起来的确是件非常不可思议的事情,工程量非常的巨大,但正是如此伟大的...
用户411565 2012-04-06 21:33
科学仪器网络模型
科学仪器概述     科学仪器发展趋势 科学是从测量开始的,科学仪器是信息技术的源头,是信息产业的重要组成部分,是现代科学与工业的基石。科学仪器产业的发展关系到国家科学研究实力、生...
用户411565 2012-04-06 21:16
谈谈RAID产品与技术
说起RAID,学计算机的同学马上会说RAID技术简单啊,就是将数据条带化,然后计算一些冗余数据,一并写入磁盘。通过RAID技术一方面提高系统的IO性能;另一方面提高系统的可靠性。单纯从RAID的原...
我要评论
1
9
关闭 站长推荐上一条 /2 下一条