Chinaunix首页 | 论坛 | 博客
  • 博客访问: 533889
  • 博文数量: 103
  • 博客积分: 2024
  • 博客等级: 上尉
  • 技术积分: 1294
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-08 21:17
文章分类

全部博文(103)

文章存档

2012年(2)

2011年(21)

2010年(80)

分类: LINUX

2010-03-09 13:33:38

转自http://www.52rd.com/blog/Detail_RD.Blog_sbz_4327.html

设备驱动程序大概可分为两种

内核驱动程序及用户空间驱动程序。
内核驱动程序

是内核空间实现的驱动程序,它使用内核资源,内核栈。它包括可加载的内核驱动模块。在这里我想主要说说用户空间驱动程序的编写。

用户空间驱动程序

就是指在用户空间实现的驱动程序。可以认为,它跟普通的用户程序没有什么两样,它使用用户进程空间和栈。这里说下,我不是讨论接到串口,并口上什么设备!
大家不要以为在用户空间写驱动程序“不过瘾!”。其实,作为设备驱动程序,其主要做的事就是配置设备寄存器(一家之言)。所以也不用把驱动程序看得那么“神秘”。当然,有些设备是不合适在用户空间实现驱动的。个人认为,使用中断的设备不宜在用户空间驱动,除此外,都有办法在用户空间来驱动。
在用户空间实现驱动的一个好处就是,方便用GDB调试。

怎么写

上面说到,驱动程序主要做的事情就是配置设备寄存器。那么,只要在用户空间,我能获得到寄存器地址(或是映像地址)那就可以驱动这个设备了。
以PCI设备为例,假设你的PCI设备主芯片的配置寄存器在PCI配置头的0x14位置:
首先:通过/proc文件系统的pci文件,及/proc/bus/pci目录下的文件,可以获取到你的设备PCI配置头的信息,当然,也可以读出0x14偏移的值。假设其值为0xE0080000;这个就是你的PCI设备主芯片的配置寄存器的物理地址。在有MMU的处理器里,直接使用这个地址是不允许的。我们都知道,在用户进程空间寻址一个物理地址,首先要把这个物理地址映射到进程空间内。

怎么映射呢?
我们知道,在Linux的/dev目录下,有一个mem的设备。我们简单认为它就是管理0x00000000-0xFFFFFFFF(32位处理器)物理地址的一个设备(不单指物理内存,它的空间也含盖了PCI地址空间)。将PCI配置寄存器空间映射到进程空间的逻辑如下:

fd = open("/dev/mem",O_RDWR);
reg_addr = mmap(NULL,0x100,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0xE0080000);
之后,你就可以使用reg_addr这个地址,在0x100大小空间范围内配置你的PCI设备了。

就这么完了吗

在用户空间实现的驱动程序,不用为设备建立设备文件。当然,在多个进程使用时,要使用IPC机制来实现设备临界区的保护等。如果你真的感觉写用户空间的设备驱动程序“没什么水平”,那你可以用它来调试好你的设备(也是就知道怎么设置寄存器)后,再花一点时间把它移到内核去,加上文件系统接口,使用内核同步机制进行同步,再实现初始化函数,就可以变成内核驱动了。

阅读(967) | 评论(0) | 转发(0) |
0

上一篇:linux线程浅析

下一篇:中断现场保护

给主人留下些什么吧!~~