日期:2014-05-16  浏览次数:20665 次

关于linux块设备驱动程序的两个问题
我们都知道,写linux块设备驱动的本质大部分都是对寄存器读写(这是我假设,有待确认)
我想问的是:
1. 我们如何知道这些寄存器的地址的?是谁告诉的。
2. 应用程序如何对这个块设备进行读写,是通过ioctl还是其他方法?
谢谢。/

------解决方案--------------------
1、别的问题不论 单说对存储设备的读写操作寄存器 要注意这个问题本身是有问题的。大多数情况下不可能直接读写具体的存储设备的“寄存器”。

目前常见的存储设备,ide硬盘 sata硬盘 u盘 sd卡 cf卡 norfalsh nandflash
都有各自的规范和标准,如何操作这些存储设备或者发送专用的存储操作命令,lz可以找到对应的规范手册慢慢研读
注意,这些标准和规范仅限于存储设备和存储设备的硬件控制器之间

存储设备的硬件控制器离具体的存储设备还隔了一层。即使是驱动程序,也无法直接操作具体的存储设备,例如你可以给通过ide控制器的寄存器给硬盘发ide命令,但不能直接操作硬盘。可以通过usb主控器给u盘发scsi命令,但不能直接操作u盘。只能读写硬件控制器的寄存器

这些硬件控制器的制造商会提供datasheet,描述这个总线控制器的寄存器每一位的意义。但一般不会告诉你如何访问这些寄存器。

如何访问具体的存储设备的硬件控制器的寄存器,就看这个存储设备的主控器的上一级(向cpu方向)直接物理连接是什么总线
例如ide控制器 sata控制器 usb控制器,在x86上往往是挂在南北桥扩出来的pci总线上,此时需要lz按照pci设备驱动的惯例,读取pci配置空间,pci_iomap,然后就能操作这些寄存器了
但是在嵌入式cpu如arm powerpc上,ide控制器 sata控制器 usb控制器 falsh控制器,大多直接接在soc的前端总线上,此时这些控制器的地址都是soc能直接寻址的,你能在soc的datasheet上直接找到这些存储控制器的物理地址,ioremap之后就能读写


再啰嗦一句,上面这一段就引出一个容易被忽视但很重要的问题----就是物理总线的主控制器端和这条物理总线的设备端,各自都有驱动程序。pci有pci主控器驱动和pci设备驱动 usb也一样 i2c也一样
一般总线控制器的驱动是这个控制器芯片的厂商提供,甚至都加入了主线内核,一般就容易被忽视。
总线控制器的驱动提供这条总线上的探测、读写、映射、dma等操作的封装接口。至于总线那头具体的设备,例如不同厂商的硬盘和u盘,这些设备的驱动属于设备端驱动。设备端驱动要调用总线控制器驱动提供的接口才能操作设备。

对于存储设备,有一个好玩的现象,就是设备端驱动几乎一样,但是控制器的驱动却多种多样。
norfalsh nandflash ,它们的设备驱动几乎是通用的,而具体的flash控制器的驱动各不相同的。
硬盘 u盘的驱动大多是一样,usb总线控制器的驱动各不相同。


喝咖啡了太兴奋 写了一堆 

------解决方案--------------------
1. 我们如何知道这些寄存器的地址的?是谁告诉的。

写逻机程序时,寄存器的地址来源于CPU数据手册。在LINUX下,一般的CPU的厂商都写好有相应的头文件,自己查一下,直接调用即可。

2. 应用程序如何对这个块设备进行读写,是通过ioctl还是其他方法?

对字符车陂或者是块设备进行读写,最好都是按照LINUX或原厂商的驱动程序架构来写。ioctl是重点内容。一般的至少包含下述几个模块:
 file_operations,open,init,ioctl,exit,
 module_init,module_exit,MODULE_LICENSE
------解决方案--------------------
探讨

1、别的问题不论 单说对存储设备的读写操作寄存器 要注意这个问题本身是有问题的。大多数情况下不可能直接读写具体的存储设备的“寄存器”。

目前常见的存储设备,ide硬盘 sata硬盘 u盘 sd卡 cf卡 norfalsh nandflash
都有各自的规范和标准,如何操作这些存储设备或者发送专用的存储操作命令,lz可以找到对应的规范手册慢慢研读
注意,这些标准和规范仅限于存储设备和存……