当前位置:嗨网首页>书籍在线阅读

19-实例2_IDE硬盘设备驱动

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

13.8 实例2:IDE硬盘设备驱动

IDE(Integrated Drive Electronics)接口,也就是集成驱动器电路接口,原名为ATA(AT Attachment,AT嵌入式)接口,其本意为将硬盘控制器与盘体集成在一起的硬盘驱动器,经历了ATA-1到ATA-7以及SATA-1和SATA-2的发展历史。ATA-1至ATA-4采用40芯排线缆,ATA-5至ATA-7则采用40针80芯线缆,虽然线缆数量增加了,但是逻辑原理没有变,只是通过物理上的改变来达到改善PCB信号完整性的目的,它提供更多的地线并使信号线临近地线,从而减少电流回流的面积。SATA-1和SATA-2与ATA-1至ATA-7相比,数据传输方式由并行转变为串行。

IDE接口的硬件原理实际上非常简单,对CPU的外围总线进行简单扩展后就可外接IDE控制器,表13.1所示为40针IDE接口的引脚定义。

表13.1 IDE接口的引脚定义

| 引脚 | 信 号 | 信 号 描 述 | 信号方向 | 引脚 | 信 号 | 信 号 描 述 | 信号方向 | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | 1 | RSET | 复位 | I | 21 | DMARQ | DMA请求 | O | | 2 | GND | 地 | I/O | 22 | GND | 地 | | 3 | DD7 | 数据位7 | I/O | 23 | | 写选通 | I | | 4 | DD8 | 数据位8 | I/O | 24 | GND | 地 | | 5 | DD6 | 数据位6 | I/O | 25 | | 读选通 | I | | 6 | DD9 | 数据位9 | I/O | 26 | GND | 地 | | 7 | DD5 | 数据位5 | I/O | 27 | IORDY | 通道就绪 | O | | 8 | DD10 | 数据位10 | I/O | 28 | DPSYNC:CXE L | 同步电缆选择 | | 9 | DD4 | 数据位4 | I/O | 29 | | DMA应答 | O | | 10 | DD11 | 数据位11 | I/O | 30 | GND | 地 | | 11 | DD3 | 数据位3 | I/O | 31 | | 中断请求 | O | | 12 | DD12 | 数据位12 | I/O | 32 | | 16位I/O片选 | O | | 13 | DD2 | 数据位2 | I/O | 33 | DA1 | 地址1 | I | | 14 | DD13 | 数据位13 | I/O | 34 | | 诊断完成 | O | | 15 | DD1 | 数据位1 | I/O | 35 | DA0 | 地址0 | I | | 16 | DD14 | 数据位14 | I/O | 36 | DA2 | 地址2 | I | | 17 | DD0 | 数据位0 | I/O | 37 | | 片选0 | I | | 18 | DD15 | 数据位15 | I/O | 38 | | 片选1 | I | | 19 | GND | 地 | | 39 | | 驱动器状态指示 | O | | 20 | N.C | 未用 | | 40 | GND | 地 |

IDE控制器提供了一组寄存器,通过这些寄存器,主机能控制IDE驱动器的行为和查询其状态,表13.2所示IDE接口寄存器的定义。

表13.2 IDE接口寄存器定义

| 片选1 | 片选0 | 地址2 | 地址1 | 地址0 | 读 | 写 | 位数 | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | 1 | 0 | 0 | 0 | 0 | 数据寄存器 | 数据寄存器 | 16 | | 1 | 0 | 0 | 0 | 1 | 错误寄存器 | 特征寄存器 | 8 | | 1 | 0 | 0 | 1 | 0 | 扇区数寄存器 | 扇区数寄存器 | 8 | | 1 | 0 | 0 | 1 | 1 | 扇区号寄存器 | 扇区号寄存器 | 8 | | 1 | 0 | 1 | 0 | 0 | 柱面号寄存器(低8位) | 柱面号寄存器(低8位) | 8 | | 1 | 0 | 1 | 0 | 1 | 柱面号寄存器(高8位) | 柱面号寄存器(高8位) | 8 | | 1 | 0 | 1 | 1 | 0 | 驱动器选择/磁头寄存器 | 驱动器选择/磁头寄存器 | 8 | | 1 | 0 | 1 | 1 | 1 | 状态寄存器 | 命令寄存器 | 8 | | 0 | 1 | 1 | 1 | 0 | 状态寄存器 | 设备控制器寄存器 | 8 |

IDE硬盘的传输模式有以下3种。

● PIO(Programmed I/O)模式:PIO模式是一种通过CPU执行I/O端口指令来进行数据读写的数据交换模式,是最早的硬盘数据传输模式,数据传输速率低下,CPU占有率也很高。

● DMA(Driect Memory Access)模式:DMA模式是一种不经过CPU而直接从内存存取数据的数据交换模式。PIO模式下硬盘和内存之间的数据传输是由CPU来控制的;而在DMA模式下,CPU只需向DMA控制器下达指令,让DMA控制器来处理数的传送,数据传送完毕再把信息反馈给CPU,这样就在很大程度上减轻了 CPU资源占有率。

● Ultra DMA(简称UDMA)模式:它在包含了DMA模式的优点的基础上又增加了CRC校验技术,提高数据传输过程中的准确性,安全性得到保障。另外,在以往的硬盘数据传输模式下,一个时钟周期只传输一次数据,而在UDMA 模式中逐渐应用了Double Data Rate(双倍数据传输)技术,它在时钟的上升沿和下降沿各自进行一次数据传输,使数据传输速度成倍增长。

除了可以以CHS(Cylinder、Head和Sector)的方式定位硬盘的扇区外,还可以用LBA(逻辑块线性地址)的方式来定位,CHS可以换算为LBA。CHS设计最多只允许65536个柱面、16个磁头以及255个扇区/磁轨。这就将容量限制为267386880个扇区,即大约137GB。

假设用c表示当前柱面号,h表示当前磁头号,cs表示起始柱面号,hs表示起始磁头号,ss表示起始扇区号,ps表示每磁道有多少个扇区,ph表示每柱面有多少个磁道(一般情况下,cs = 0、hs = 0、ss = 1、ps = 63、ph = 255),LBA与CHS有如下对应关系:

lba=(c-cs)phps+(h-hs)*ps+(s-ss)

LBA使得系统忽略硬盘的几何结构,交由驱动器来完成。系统不需要去查询 CHS 值,而只需要查询逻辑块地址(Logical Block Address,LBA),驱动器电子装置会找出要读或写的实际扇区。而LBA48(48位逻辑块地址)则可以使系统支持超过137GB的硬盘。

Linux内核中,早期常使用drivers/ide目录下的驱动,而如今在嵌入式系统中则多使用drivers/ata下的驱动,尤其值得一提的是drivers/ata/的pataplatform.c和pata*.c文件联合起来实现了一个平台无关的并行ATA驱动,这种情况下,连接了嵌入式硬盘的电路板只需要在板文件中添加与并行ATA设备相关的平台设备和资源信息即可,不需要编写一行驱动代码就可以让硬盘工作。代码清单13.20给出了arch/arm/mach-rpc/riscpc.c板文件中新增pata_platform设备的例子。

代码清单13.20 使用pata.platform驱动连接IDE硬盘

1 static struct pata_platform_info pata_platform_data = {

2 .ioport_shift = 2,

3 };

4

5 static struct resource pata_resources[] = {

6 [0] = {

7 .start = 0x030107c0,

8 .end = 0x030107df,

9 .flags = IORESOURCE_MEM,

10 },

11 [1] = {

12 .start = 0x03010fd8,

13 .end = 0x03010fdb,

14 .flags = IORESOURCE_MEM,

15 },

16 [2] = {

17 .start = IRQ_HARDDISK,

18 .end = IRQ_HARDDISK,

19 .flags = IORESOURCE_IRQ,

20 },

21 };

22

23 static struct platform_device pata_device = {

24 .name = "pata_platform",

25 .id = -1,

26 .num_resources = ARRAY_SIZE(pata_resources),

27 .resource = pata_resources,

28 .dev = {

29 .platform_data = &pata_platform_data,

30 .coherent_dma_mask = ~0, / grumble /

31 },

32 };

上述代码中的两个IORESOURCE_MEM资源对应于IDE硬盘连接的两个内存区域。IORESOURCE_IRQ资源是硬盘使用的CPU的中断号。