Memòria del projecte en format PDF

Anuncio
Desarrollo de software de control para acceso a discos
duros SATA
TITULACIÓN: Ingeniería Técnica Industrial en Electrónica Industrial
AUTOR: Mohamed Anaimi
DIRECTOR: Esteban del Castillo Pérez
FECHA: Septiembre del 2010
Índice 1 Introducción .................................................................................................5 2 Objetivo.........................................................................................................7 3 Especificaciones previas ..............................................................................8 4 Antecedentes.................................................................................................9 4.1 La evolución de los discos ............................................................................... 9 4.2 Elementos que hacen posible el funcionamiento del disco SATA ............. 13 4.2.1 Ordenador............................................................................................................ 13 4.2.2 Disco SATA: ........................................................................................................ 13 4.2.3 Advanced Host Controller Interface (AHCI) ..................................................... 14 4.3 Interfaz de usuario (parte gráfica)............................................................... 15 4.4 Beneficios del programa de gestión del disco.............................................. 16 5 Análisis previo ............................................................................................17 6 Disco SATA.................................................................................................18 6.1 El Hardware (el nivel físico) ......................................................................... 18 6.1.1
6.1.2
6.1.3
6.1.4
Spread Spectrum Clocking.................................................................................. 18 Cables y Conectores ............................................................................................ 18 Señales OOB (Out Of Band).............................................................................. 20 Secuencia de inicialización del phy ................................................................... 21 6.2 El nivel de Enlace........................................................................................... 21 6.2.1 Codificación 8b10b: Caracteres de datos, caracteres de control y patrón Coma
........................................................................................................................................ 21 6.2.2 Primitivas y Tramas ............................................................................................ 23 6.3 El nivel de Transporte................................................................................... 25 6.3.1 Modos de transferencia ....................................................................................... 25 6.3.1.1 Programmed I/O ............................................................................................ 26 6.3.1.2 DMA .............................................................................................................. 27 6.3.1.3 ULTRA DMA................................................................................................ 30 6.3.2 Los registros Shadow .......................................................................................... 32 6.3.2.1 Registro de comandos .................................................................................... 33 6.3.2.2 Puerto de datos............................................................................................... 34 6.3.2.3 Registro de datos............................................................................................ 35 6.3.2.4 Registro del dispositivo ................................................................................. 36 6.3.2.5 Registro de control del dispositivo ................................................................ 37 6.3.2.6 Registro de errores ......................................................................................... 38 6.3.2.7 Registro de características.............................................................................. 39 6.3.2.8 LBA alto ........................................................................................................ 40 6.3.2.9 LBA bajo........................................................................................................ 41 6.3.2.10 LBA medio .................................................................................................. 42 6.3.2.11 Registro de cuenta de sectores ..................................................................... 43 2
6.3.2.12 Registro de estado ........................................................................................ 44 6.3.2.13 Registro de estado alternativo...................................................................... 45 6.3.3 FIS (Frame Information Structure)................................................................... 46 6.3.4 Nuevo bloque de registros SATA ........................................................................ 47 6.3.5 Direccionamiento 48-bit...................................................................................... 48 6.3.6 Descripción de comandos.................................................................................... 50 6.3.5.1 Read Sectors .................................................................................................. 50 6.3.5.2 Read Sectors EXT.......................................................................................... 53 6.3.5.3 Write Sectors.................................................................................................. 55 6.3.5.4 Write Sectors EXT......................................................................................... 57 6.3.5.5 Read multiple................................................................................................. 59 6.3.5.6 Read multiple EXT ........................................................................................ 61 6.3.5.7 Write multiple ................................................................................................ 62 6.3.5.8 Write multiple EXT ....................................................................................... 65 6.3.5.9 Read DMA..................................................................................................... 66 6.3.5.10 Read DMA EXT .......................................................................................... 68 6.3.5.11 Write DMA .................................................................................................. 69 6.3.5.12 Write DMA EXT ......................................................................................... 71 6.3.5.13 Identify Device ............................................................................................ 72 6.3.5.14 Device reset.................................................................................................. 74 6.4 SATA II .......................................................................................................... 75 6.4.1
6.4.2
6.4.3
6.4.4
Extensiones de SATA .......................................................................................... 75 Multiplicador de Puertos..................................................................................... 75 Selector de Puerto................................................................................................ 76 Cables y Conectores ............................................................................................ 76 7 El lenguaje de programación C ................................................................77 8 Desarrollo del software..............................................................................79 8.1 Parte gráfica: ................................................................................................. 80 8.2 Parte funcional: ............................................................................................. 83 8.3 Pasos para la realización del software ......................................................... 86 9 Resultados finales.......................................................................................88 9.1
9.2
9.3
9.4
9.4
La función Editar .......................................................................................... 88 La opción Copiar ........................................................................................... 89 La opción Comparar ..................................................................................... 90 La opción Buscar ........................................................................................... 91 La opción Configurar.................................................................................... 92 10 Manual de instalación y uso....................................................................93 10.1 Instalación del disco duro SATA................................................................ 93 10.2 Instalación del sistema operativo MS-DOS............................................... 94 11 Presupuesto...............................................................................................96 12 Conclusiones .............................................................................................97 13 Bibliografía y referencias ........................................................................98 13.1 Referencias ................................................................................................... 98 13.2 Bibliografía................................................................................................... 98 3
14 Anexo.........................................................................................................99 14.1 Comandos..................................................................................................... 99 14.2 contenido de la respuesta al comando Identify device ............................ 101 14.3 Diferentes rutinas extraídas del código ................................................... 106 14.3.1
14.3.2
14.3.3
14.3.4
14.3.5
14.3.6
La función Disk_access48( )........................................................................... 106 La función x_disco48( ) .................................................................................. 110 La función main( ) .......................................................................................... 113 La rutina de atención a la interrupción ......................................................... 115 La función SetIdeDriver( ).............................................................................. 120 La función de obtención del valor tecleado.................................................... 122 4
1 Introducción
Mediante la realización de este proyecto se pretende obtener una aplicación que permita
el acceso a discos duros del tipo SATA1. La aplicación nos permitirá realizar
operaciones de búsqueda, copia, comparación y edición sobre cualquier parte de
cualquier disco duro, de este tipo o compatible, accesible en el sistema.
El usuario podrá ver la información del disco en bits i código ASCII2. El acceso será del
más bajo nivel posible, puesto que el consumidor podrá editar cualquier bit de los
sectores del disco. Este software puede ser útil para restablecer información alterada en
el disco duro, de forma que pueda ser reconocido de nuevo por el sistema operativo
quedando accesible su información (recuperación de información), para realizar copias
de seguridad con idéntico contenido (copia imagen), para realizar búsqueda de patrones
(que permita localizar ficheros posiblemente borrados), etc
Actualmente se comercializan muchas aplicaciones para Windows que permiten hacer
esta tarea. El inconveniente de estas es que en caso de fallo del sistema operativo, el
disco duro queda totalmente aislado y por tanto el acceso será imposible. Una ventaja de
este programa es que opera bajo DOS3. Esto permite un rápido acceso a las herramientas
desarrolladas en este proyecto y las hace independientes de cualquier sistema operativo
instalado en el disco dañado. Las funciones principales del programa están explicas en
el apartado Resultados finales.
ATA paralela significa conexión de tecnología avanzada en paralelo, del inglés Parallel
Advanced Technology Attachment (PATA). Ha sido la interfaz de las unidades de disco
duro de los ordenadores de sobremesa durante más de 15 años. ATA paralela se puede
encontrar en ordenadores de sobremesa, portátiles, electrónica de consumo y algunos
servidores actuales. Aún existe gran cantidad de unidades de disco duro PATA en el
mercado. Hasta que se produzca la total transición de paralelo a serie, muchos
ordenadores seguirán utilizando las unidades de disco ATA paralela.
La interfaz ATA serie (SATA) se diseñó para ser la sustituta de la interfaz ATA paralela
en los sistemas de almacenamiento de red, ordenadores de sobremesa, ordenadores
portátil y electrónica de consumo. SATA permite trasladar más datos en menos tiempo,
lo que aumenta el rendimiento y la flexibilidad. La cola de comandos nativa, una de las
características clave de SATA, hace posible ordenar y dar prioridad a varios comandos
al mismo tiempo, y reducir el desgaste mecánico de la unidad. Otras características,
como la conexión en caliente, la aceleración de giro escalonada y la velocidad de
transferencia rápida de 3 Gb/s, hacen de SATA la elección perfecta para servidores,
estaciones de trabajo, ordenadores de sobremesa, dispositivos de electrónica de
consumo y ordenadores portátiles.
1
Véase el apartado 6.0 para ver la definición y las características de los discos SATA.
El código ASCII (acrónimo inglés de American Standard Code for Information Interchange) es un
código de caracteres basado en el alfabeto latino. Fue creado en 1963. el código ASCII utiliza 7 bits para
representar los caracteres.
3 "DOS" es una familia de sistemas operativos para PC.
2
5
Tal y como hemos sido testigos durante estos últimos años, y al mismo ritmo que han
ido creciendo las prestaciones de los discos duros, los canales de comunicación por los
que circula la información entre estos y el resto del sistema ha ido sufriendo una
paulatina y en el mismo tiempo una imprescindible modernización, acorde con el cada
vez mayor caudal de datos en tránsito entre ambos extremos de la comunicación: host y
disco duro.
Esta aplicación ya fue desarrollada, por el profesor Esteban del Castillo, para discos
Parallel ATA de hasta 137 Gigabytes de memoria. Nuestro objetivo será aprovechar la
misma aplicación y mejorarla para acceder a discos Serial ATA con una limitación de
memoria mucho más superior. Para eso se tendrá que adecuar el programa de tal forma
que no se vea afectado por la enorme evolución de la capacidad de los discos duros
permitiendo el correcto funcionamiento del mismo con dispositivos cuyas prestaciones
son mejores que los actuales.
Más adelante se hará una explicación detallada de la arquitectura de los discos SATA
tanto a nivel físico y eléctrico como a nivel lógico. Esto será el punto de partida para
entender las diferencias que hay respecto a los discos PATA.
Es importante destacar que gracias a organismos como ‘Technical Committee T13’ o
bien ‘Serial ATA International Organisation’ se ha hecho posible mantener una cierta
compatibilidad entre los diferentes tipos de discos pese la complejidad de las interfaces.
Quizá el paso más significante es la conservación de elementos, en las especificaciones
del Serial ATA, que permiten el funcionamiento del ATA paralelo.
El controlador SATA por un lado emula el funcionamiento de un interfaz ATA
estándar, lo que permite a los programas BIOS y drivers actuales (denominados
genéricamente software Heredado) acceder a los dispositivos SATA como si se trataran
de dispositivos estándar ATA, y por otro implementa nuevos recursos para permitir que
drivers SATA de nuevo desarrollo (software Nativo) puedan acceder a las nuevas
funcionalidades y posibilidades del interfaz SATA.
Para la realización de este proyecto vamos a tener que programar tanto a alto nivel (C)
como a bajo nivel (ensamblador). Afortunadamente disponemos de una herramienta
sencilla de programación (Borland C) que permite enlazar ficheros de los dos tipos y
generar el ejecutable (.exe) deseado para Disk Operating System.
6
2 Objetivo
El objetivo principal de este proyecto es la realización de una aplicación que permita el
acceso directo del usuario a los discos duros SATA. La aplicación está diseñada tanto
para usuarios con pocos conocimientos de informática como para programadores y
personal de mantenimiento.
Para realizar dicho proyecto se conseguirán otros dos objetivos didácticos: el primero es
el conocimiento de los dispositivos de almacenamiento masivo, para conseguir esta
información se consultarán manuales de fabricantes, documentos de especificaciones y
también estándares publicados.
El otro objetivo tiene que ver con la aplicación de los conocimientos adquiridos con los
estudios de la carrera. Se trata de la profundización en la programación en lenguaje C
sobre plataforma PC. Esto hace de este proyecto un importante complemento de
formación, y posiblemente una continuación de la asignatura INFORMATICA
INDUSTRIAL II.
7
3 Especificaciones previas
Para la realización de este proyecto se marcaran las siguientes especificaciones previas:
• El software debe desarrollarse en lenguaje de programación C.
• Como paso previo, la realización de un código con una interfaz simple de lectura
y escritura en el disco.
• Se tendrá que mantener la compatibilidad con el programa original.
• Se debe utilizar la interfaz facilitada y adecuarla para cantidades superiores de
memoria.
• Las modificaciones hechas en el programa original no deben afectar en ningún
caso las funciones ya implementadas.
El lenguaje de programación para este proyecto será el C, un código de fácil manejo con
gran compatibilidad con muchos PCs. Este código permite programar tanto a alto nivel
como a bajo nivel. Es importante destacar que se incluye en el proyecto un fichero
hecho en lenguaje ensamblador, este último es para el manejo de las interrupciones
donde es imprescindible la reducción de los tiempos de ejecución del código.
El código que se tiene que realizar en la fase previa es totalmente orientativo. Podemos
decir que es una introducción a una aplicación práctica de los conocimientos adquiridos
de los manuales de especificaciones de los discos duros. En este caso no importa la
parte grafica (interfaz de usuario) sino la parte funcional. Conseguir una simple lectura
y escritura de un sector nos abrirá muchas puertas en el entendimiento de los diferentes
métodos de acceso a estas unidades de almacenamiento.
Las especificaciones anteriores se basan en la idea de hacer un programa para gestión de
los diferentes tipos de discos duros que podemos encontrar en el mercado hoy en día.
En el mismo tiempo se hace una prevención de posibles detalles de futuros avances en
los discos duros como ahora el volumen de estos, un ámbito que avanza de forma brutal.
Vista la gran evolución de las capacidades de los discos duros, nos vemos obligados a
modificar la interfaz de usuario para una correcta visualización del número de sectores
del disco y el tamaño de este. El número de sectores a los que se pueden acceder
superará pronto el límite de tamaño de las variables que se pueden definir en C.
8
4 Antecedentes
4.1 La evolución de los discos
En 1957, se introdujo como un componente de IBM RAMAC la primera unidad de
discos duros.
Requirió 50 discos de 24 pulgadas para guardar cinco megabytes (millón bytes, se
abrevió MB) de datos y costó US$35.000 por año o arrendarlo a US$7.000 por
megabyte anual. Fue el primer ordenador comercial que utilizaba disco duro de
cabeza móvil (unidad de disco magnético) como almacenamiento secundario. IBM
lo lanzó el 4 de septiembre de 1956.
RAMAC eran las iniciales en inglés de "Sistema de Contabilidad con Memoria de
Acceso Aleatorio" ("Random Access Memory ACcounting System" . Su diseño
estuvo motivado por la necesidad de sustituir el fichero de tarjetas perforadas
utilizado por la mayoría de las oficinas de la época. El primer RAMAC destinado a
ser usado en la industria del automóvil estadounidense fue instalado en la Chrysler's
MOPAR Division en 1957. Sustituyó a un gigantesco fichero que era parte del
sistema de procesamiento para el control de inventario y pedidos de piezas de
MOPAR. El 305 fue uno de los últimos ordenadores de tubo de vacío construídos
por IBM.
El sistema de disco IBM 350 almacenaba cinco millones de caracteres de siete bits
(aproximadamente 4,2 MiB). Tenía cincuenta discos de veinticuatro pulgadas de
diámetro. Dos brazos independientes se desplazaban verticalmente seleccionar un
disco y horizontalmente para seleccionar una pista de grabación, todo para control
de servomecanismos. El tiempo medio de posicionamiento en un registro era de
seiscientos milisegundos. En la década de 1950 se añadieron varios modelos
mejorados.
El ordenador IBM RAMAC 305 con almacenamiento en disco 350 tenía un coste en
"leasing" de 3.200 dólares mensuales en dólares de 1957, equivalente a un precio de
compra de unos 160.000 dólares. Se construyeron más de 1.000 unidades. La
producción terminó en 1961, el RAMAC pasó a ser obsoleto en 1962 con el
lanzamiento del IBM 1401 y retirado del mercado en 1969.
En el 1962 IBM introdujo un nuevo modelo, el 1301, con una capacidad de 28 MB
y una velocidad de transferencia y una densidad de área 10 veces mayor que el
RAMAC 305. La distancia entre los cabezales y la superficie del disco había
descendido desde 20,32 µm a 6,35 µm.
A partir del año 1962, muchos fabricantes comenzaron a vender discos duros como
el 1301. La Unidad de almacenamiento en disco de IBM, con su mayor capacidad,
flexibilidad y velocidad, se ha ampliado la capacidad operativa de la serie 7000 de
los ordenadores de IBM (7070, 7094, 7080 y 7090).
9
Figura 1. El modelo 1301 con 28MB de memoria
Utilizado en combinación con la serie 7000, el 1301 había muchos de los mismos y las
características físicas generales de funcionamiento como cuando se utiliza con el IBM
1410 Data Processing System. Estas características incluyen: el concepto del cilindro
(verticalmente alineados de lectura / escritura cabezas, una a una superficie del disco,
para proporcionar la lectura y escritura de información en temas relacionados con el
disco correspondiente y para eliminar la necesidad de acceso para el movimiento
vertical); longitud de registro flexibles (diferentes registros de longitud podría ser
almacenados en el archivo, aumentando enormemente la capacidad de almacenamiento
real); y selectiva frente (números de registro fueron asignados por el usuario para una
mayor eficacia en muchos puestos de trabajo, las direcciones no tienen que ser
consecutivos, secuencial o numérico).
El 1301 de los discos giran a 1.800 rpm. El 1301 proporcionó las 50 pistas por pulgada
y grabación de hasta 520 bits por pulgada de pista (gracias a una reducción media en la
cabeza-a-distancia de la superficie de 800 a 250 micropulgadas). Como resultado, la
capacidad de almacenamiento por pulgada cuadrada de la superficie se incrementó 13
veces más de lo que había sido con la tecnología de IBM RAMAC de 1956.
El Modelo 1 de la 1301 había un módulo, el Modelo 2 con dos módulos. Módulo de la
capacidad de la 1301 utilizadas con 7000 equipos de la serie fue de 28 millones de
caracteres, que se utiliza con el equipo del 1410, la capacidad del módulo fue de 25
millones de caracteres. Hasta el 10 módulos (cinco unidades de 1301) podría ser
incorporada - 7631 utilizando el archivo de la unidad de control de IBM, y en algunos
casos, los adaptadores y los canales de datos - a un sistema informático, proporcionando
una capacidad máxima de 280 millones de caracteres de la serie 7000 máquina y 250
millones para el 1410.
10
Fabricado en la planta de IBM en San José, California, los 1301s fueron entregados a
los clientes en el tercer trimestre de 1962. (A pocos días antes del 1301 se anunció
oficialmente en junio de 1961, un modelo de ingeniería del 1301 fue enviado a IBM en
Poughkeepsie, NY, instalaciones para el uso en las pruebas del famoso sistema SABRE
reserva. Más tarde, en pleno funcionamiento, el sistema SABRE adjunta seis tambores
magnéticos de almacenamiento y 16 de IBM 1301s.)
El Modelo 1 con un costo módulo de $ 2.100 por mes para alquilar o podrían ser
comprados por 115.500 dólares. El Modelo 2 con dos módulos de un costo de $ 3.500
por mes para alquilar o 185.500 dólares a la compra.
Figura 2. El modelo 2310
En 1965, IBM lanzó el modelo 2310, cuya notable característica era ser un elemento de
almacenamiento desmontable (el primer disco flexible). En abril de 1967, IBM anunció
una expansión de cuatro modo de sistema de 1130. Nuevas características para el
escritorio de computadora del tamaño de IBM más pequeño a la vez, incluyó la
capacidad de leer la información de cinco discos magnéticos al mismo tiempo.
Anteriormente, sólo un equipo autónomo de disco (primer plano) estaba disponible. Sin
embargo, en 1967, hasta cuatro discos adicionales (a la derecha, parte trasera) se podría
agregar. Cada uno puede almacenar hasta un millón de caracteres de información.
El 2314, lanzado en 1966, tenía cabezales de lectura de ferrita (óxido de hierro).
Anunció un año después de la System/360 en abril de 1965, el IBM 2314 proporcionó
ocho unidades de disco y una de repuesto, junto con una unidad de control en una
misma instalación. Un paquete nuevo disco con 11 discos duplicó el número de
superficies de almacenamiento de más de los disponibles en el paquete de la primera de
11
disco extraíble. La densidad de grabación el incremento de la capacidad de
almacenamiento de 29,2 millones de bytes por paquete o 233 millones de bytes en las
ocho instalaciones de carga.
El tiempo de acceso y la latencia de la 2314 era la misma que la de más edad de IBM
2311, pero el 2314 ofrece el doble de la velocidad de datos de 310.000 bytes por
segundo. El 2314 también fue interesante porque era cuatro veces menor en el precio
por megabyte de almacenamiento.
Ayudado por OS/360 - s el IBM S/360 'del sistema operativo - el 2314 grandes bases de
datos les permite tener acceso, y el sistema pasó de un trabajo a otro de forma
automática siempre y cuando las instrucciones necesarias y los datos fueron en línea.
Algunos observadores han dicho que OS/360 ayudado a hacer del 2314 el producto de
almacenamiento más rentable que el tiempo y que el 2314 ha contribuido al éxito de la
IBM S/360.
En enero de 1969, IBM anunció dos nuevas versiones del 2314 - la A1 1 Modelo y
Modelo 1 A2 - cada uno con un tiempo de acceso un 20 por ciento más rápido que el
disponible anteriormente Modelo 1. Uno de los nuevos modelos de almacenamiento en
disco con cinco unidades de disco independiente, y el otro tenía ocho. La versión de
cinco unidades con una capacidad de almacenamiento de 145,8 millones de bytes; la
más grande tenía una capacidad de 233,4 millones de bytes. El tiempo de acceso
promedio se redujo en 75 a 60 milisegundos. El tiempo de acceso mínimo era de 25
milisegundos.
Las nuevas versiones incluidas sus unidades de control propio y han sido diseñados para
su uso con S/360 Modelos 30, 40, 50, 65, 67, 75 y 85. El más pequeño de 2314 alquiló
3.875 dólares al mes y se vendió por $ 175.075. La versión más grande de alquiler de
5.675 dólares al mes, con un precio de compra de 256.400 dólares. Primer cliente de los
envíos se habían programado para el tercer trimestre de 1969.
Más tarde, en 1969, una caja con dos unidades que se ofrecía. En 1970, la unidad de
almacenamiento de 2319 se ha configurado con tres unidades de 2314, más la
electrónica de control para la adhesión a los más pequeños de la recién anunciada
System/370 transformadores.
En el 1980 se hizo el primer disco duro de 5,25" (cinco-coma-veinticinco pulgadas),
desarrollado por la compañía Seagate. La revolución de la computadora personal a
comienzos de 1980 cambió todo, es la introducción de los primeros discos duros
pequeños. Eran discos de 5.25 pulgadas los que manejaban de 5 a 10 MB de
almacenamiento- el equivalente de 2.500 a 5.000 páginas de tecleo de información- en
un aparato del tamaño de la caja de un zapato pequeño. Al tiempo se consideró que una
capacidad de almacenamiento de 10 MB era demasiado grande para una llamada
computadora "personal". Los primeros PCS usaron discos flexibles trasladables como
aparatos de almacenamiento casi exclusivamente. El término "disco blando" con
precisión se refiere a los primeros discos para PC de 8 y 5.25 pulgadas que tuvieron
éxito. Los discos internos de hoy, más pequeños, se construyen 3.5 pulgadas de forma
similar a los anteriores, pero se albergan en un casco de plástico rígido, que es más
durable que el techado flexible de los discos más grandes.
12
Alrededor de 1992 varios modelos 1.8 pulgadas aparecieron, peso sólo unas onzas y
entrega capacidades de hasta 40 MB. Igualmente aparecieron con formato de 1.3
pulgadas, del tamaño de una fosforera. Factores de forma más pequeños por supuesto,
no eran necesariamente mejor que los más grandes.
En el periodo entre 1995 y 1999 el disco duro más pequeño que puede encontrarse en
ésta época es el de 4 GB, mientras que el más grande es de 15 GB. Podría decirse que
los discos duros de cualquier tamaño, permiten instalar Windows, Office y un programa
de contabilidad, y aún sobrará capacidad para, digamos, unas 50.000 cartas y varios
millones de apuntes bancarios.
En la actualidad, ya contamos en el uso cotidiano con discos duros de más de un
terabyte (TB) o 1.048.576 megabytes.
4.2 Elementos que hacen posible el funcionamiento del disco SATA
4.2.1 Ordenador
Este puede ser portátil o de sobremesa. Contiene todos los dispositivos que nos
permiten, entre otras cosas, el acceso al disco. Podemos incluir también todos los
periféricos como ahora el teclado, el ratón y la pantalla. La placa base tiene que ser
compatible con los discos SATA de grandes capacidades.
4.2.2 Disco SATA:
Figura 3. Disco Serial ATA
13
Se trata de un disco duro con una interfaz serie de transferencia de datos con la placa
base. Un hecho ya conocido es que con estos discos se alcanzan velocidades de
transferencia muy superiores a los discos que usan la conexión paralela.
La primera generación especifica en velocidades de 1.5 Gbit por segundo, también
conocida por SATA 1.5 Gb/s o Serial ATA-150. Actualmente se comercializan
dispositivos SATA II, a 3 Gb/s, también conocida como Serial ATA-300 y los SATA
III, a 6 Gb/s, que incluyen una velocidad de 6.0 Gb/s estándar. Los discos que soportan
la velocidad de 3Gb/s son compatibles con un bus de 1,5 Gb/s.
4.2.3 Advanced Host Controller Interface (AHCI)
Este dispositivo se encarga de emular el funcionamiento de un interfaz ATA estándar. La
emulación puede consistir en presentar los dispositivos como si fueran Maestros de
distintos puertos ATA, o presentarlos por parejas como si fueran Maestro y Esclavo de
un puerto ATA. La emulación es completa, tanto a nivel del comportamiento del
controlador como de los dispositivos, incluyendo el comportamiento de los bloques de
registros de Comando y de Control, las transferencias en modo PIO, DMA y UDMA,
las interrupciones y los distintos procesos de inicialización.
En el interfaz paralelo, toda la comunicación a nivel de comandos, datos y estado entre
un dispositivo y el driver se hace mediante los registros de Comando y de Control
situados en el propio dispositivo. Cada dispositivo dispone de su propio bloque de
registros y el driver lee y escribe directamente en ellos. Las direcciones de los registros
son distintas para cada puerto ATA, pero son las mismas tanto para el Maestro como
para el Esclavo de cada puerto, debiendo el driver seleccionar previamente a uno de
ellos mediante la escritura de un bit de selección de dispositivo en uno de los registros.
El dispositivo que no está seleccionado simplemente no hace caso a ninguna lectura o
escritura en el bloque de registros, salvo las escrituras de dicho bit para detectar cuándo
el driver lo selecciona para comunicarse con él.
En el caso del interfaz SATA, el driver no puede evidentemente leer y escribir
directamente en los registros de los dispositivos, por lo que el controlador SATA
implementa un bloque de registros por cada dispositivo (denominado Bloque de
Registros Shadow) que refleja el contenido y el comportamiento de los registros de los
dispositivos. El driver entonces lee y escribe realmente en el bloque de registros shadow
del controlador SATA, mientras que por el otro lado el controlador y los dispositivos
SATA se intercambian la información a través de la línea serie para sincronizar los
contenidos de los registros. En el caso de una emulación Maestro/Esclavo, es
responsabilidad del controlador SATA enviar la información al dispositivo adecuado, en
función del bit de selección de dispositivo escrito previamente por el driver en el
registro shadow correspondiente.
14
4.3 Interfaz de usuario (parte gráfica)
Como ya se ha comentado anteriormente, en este proyecto no se tendrá que hacer una
interfaz de usuario puesto que ya disponemos de una diseñada para un programa de
acceso a discos PATA.
Disponemos de una interfaz muy completa que incluye prácticamente todas las opciones
necesarias para la gestión de los discos duros. Esta interfaz permite elegir, en caso de
varios discos, el dispositivo que se desea visualizar, editar, copiar, etc. La lista de los
dispositivos disponibles y su información correspondiente se visualiza nada más al
iniciar el programa.
La interfaz está diseñada para acoplar trozos de código en forma de ficheros de un único
proyecto donde se hará la comparación de discos, copia de una unidad a otra, búsqueda
de información en modo binario o ASCII y por supuesto la edición manual de los
sectores de los discos.
Figura 4. Portada de la interfaz ejecutada en Windows (no permite ver discos)
La capacidad de almacenamiento de los discos SATA, en la mayoría de los casos, es
muy superior a los dispositivos con conexión paralela. Por esta razón, la interfaz
necesita unas actualizaciones, sobre todo cuando se imprime por pantalla el tamaño del
disco en Megabytes.
La interfaz permite la posibilidad de acceso a cualquier sector del disco. Para ello el
usuario podrá ir avanzando los sectores de uno en uno o bien introducir de forma
numérica el orden del sector que quiere visualizar o editar. Las variables que contienen
estos datos próximamente no podrán contener todo el valor. Quizá este sea uno de los
detalles más importantes que se tendrán en cuenta como previsión de la evolución de las
capacidades de almacenamiento de los discos duros.
15
4.4 Beneficios del programa de gestión del disco
• Es un recurso flexible y adaptable a diferentes tipos de usos. El programa puede
ser usado por programadores para corrección de sectores dañados, eliminación
de datos y ficheros que afectan el correcto funcionamiento del sistema…también
la aplicación puede servir como simple herramienta para hacer copias de
seguridad o bien copia de datos de unos discos a otros.
• Con este programa se consigue reducir de forma significativa el tiempo que dura
una transferencia de datos de un disco duro: un ejemplo comprobado es el hecho
de copiar 122 GB de memoria de un disco a otro en una hora y media. Mover
esta cantidad de datos en Windows de un disco a otro puede tardar diez veces
más.
• El usuario se enfrenta a una tecnología sencilla, especialmente si se compara con
otras herramientas para este fin.
• El programa no necesita ningún tipo de instalación. Solo se tendrá que acceder a
MS-DOS ubicado en un dispositivo de almacenamiento USB y ejecutar la
aplicación. La ventaja de esto es que el acceso al disco es independiente de la
información que tiene el mismo. En Windows, el sistema operativo se ubica en
la memoria del disco duro. Si el disco está dañado no se podrá arrancar salvo
que se use otro dispositivo compatible.
• Para la mayoría de casos el uso de esta aplicación no requiere muchos
conocimientos previos. Es una aplicación intuitiva.
• El programa se podrá utilizar para la gestión de prácticamente todos los tipos de
discos duros que se pueden encontrar en el mercado. Independientemente de la
tecnología empleada y los protocolos de transferencia de datos (hay pocas
limitaciones). Se podrá acceder a discos duros de los diferentes fabricantes.
• El programa estará diseñado para gestionar discos duros con una capacidad de
almacenamiento de datos mucho más superior a la actual. Se prevé un futuro uso
de esta aplicación pese el progreso continuo en este ámbito.
16
5 Análisis previo
Antes de empezar a realizar el programa de gestión de los discos duros deben fijarnos
en las características principales que debe tener.
Disponemos de una interfaz que se tiene que acoplar al proyecto y también de un
programa ya hecho para gestión de discos duros IDE. Nuestro objetivo será hacer una
parte que trabaje en paralelo con la existente sin influir en el correcto funcionamiento de
esta.
Entonces nos encontramos con dos opciones. La primera consiste en modificar todas las
funciones del programa origen e introducir el código para el correcto funcionamiento en
los discos SATA. En este caso se emplearán condicionales en casi todas las líneas de
código en las que hay diferencia de funcionamiento.
La segunda opción es la redacción de funciones totalmente independientes para el
acceso a los disco serie y la conservación de las anteriores. En este caso, el flujo del
programa dependerá del tipo del disco (véase el apartado 8.2).
Está claro que la solución óptima es la segunda porque con esta evitaríamos tocar el
código original y nos ahorraríamos posibles errores en el funcionamiento habitual del
programa proporcionado. Aparte de eso, el código que regula las condiciones será
mínimo (solo al ejecutar una función u otra).
El inconveniente de esta solución es la extensión del código. Se puede llegar a duplicar
las líneas de código del programa y por lo tanto un aumento del tamaño del programa.
El tiempo de ejecución no se verá afectado porque, dependiendo del disco al que se
acceda, se usarán unas funciones u otras.
Un detalle muy importante que hay que tener en cuenta es la diferencia en los comandos
que se envían al disco. Hablamos de comandos para discos que implementan 28 bits
para el Direccionamiento de bloque lógico (LBA) con un máximo de 137.4 GB y otros
comandos diferentes para los dispositivos de 48 bits de direccionamiento para
capacidades muy grandes (144 Petabytes).
Por cuestiones de compatibilidad, los comandos de los discos de 28 bits suelen ser
válidos para los discos de direccionamiento superior (48 bits). Como diseño previo del
proyecto hemos decidido acceder a cada disco con los comandos propios
implementados especialmente para este, pese la existencia de la posibilidad de utilizar
los otros comandos con ciertas limitaciones. Un ejemplo de estos casos es el comando:
READ SECTOR, este comando es para discos que implementan un direccionamiento de
28 bits. Se podrá acceder a un disco de una capacidad superior a 137 GB siempre y
cuando se lea un sector con orden inferior a esta cantidad de memoria. Si pretendemos
leer un sector que se encuentra en una posición superior la lectura será errónea.
17
6 Disco SATA
El disco duro es un dispositivo de almacenamiento de datos no volátil, que conserva la
información aun con la pérdida de energía y que emplea un sistema de grabación
magnética digital. Dentro de la carcasa hay una serie de platos metálicos apilados
girando a gran velocidad. Sobre los platos se sitúan los cabezales encargados de leer o
escribir los impulsos magnéticos.
6.1 El Hardware (el nivel físico)
La interfaz SATA se compone de dos pares de señales diferenciales, una para transmitir
en un sentido y otra para transmitir en el sentido opuesto. La información se transmite
en código NRZ a una tensión nominal de +/- 250 mV. El interfaz eléctrico al cable se
realiza por medio de un transceptor denominado Phy.
Las velocidades de transmisión normalizadas por el momento son de 1,5 Gbps y 3 Gbps
(1.500 y 3.000 Mbaudios respectivamente), equivalentes a una velocidad en el enlace
físico de 150 y 300 MB/s respectivamente (ya que cada carácter se compone de 10 bits,
debido a la codificación empleada 8b10b).
6.1.1 Spread Spectrum Clocking
SATA utiliza una técnica denominada Spread Spectrum Clocking para rebajar el nivel
de emisión electromagnética, distribuyéndola en un rango de frecuencias en vez de estar
toda concentrada en una frecuencia fija. La técnica consiste en modular la frecuencia del
reloj de transmisión, de manera que la frecuencia se hace variar lentamente siguiendo
una forma triangular (decrece linealmente con el tiempo desde la frecuencia máxima
hasta una determinada frecuencia mínima, y desde ahí crece de nuevo linealmente con
el tiempo hasta la frecuencia máxima). En SATA la frecuencia máxima es igual a la
frecuencia nominal, la frecuencia mínima es el 99,5% de la frecuencia nominal, y el
periodo de la modulación triangular es de 33,33 us. Como la frecuencia se modula
desde la frecuencia nominal hacia abajo, la técnica se denomina down-spreading.
El receptor recibe los bits en código NRZ a la velocidad nominal de 1,5 ó 3 Gbps,
teniendo en cuenta las variaciones en la frecuencia de recepción debidas a la técnica de
down-spreading. A partir de la secuencia de bits el receptor recupera y deserializa los
datos (convierte la secuencia serie en paralelo), y detecta una secuencia especial de bits
denominada patrón Coma que le permite alinear los caracteres de entrada (es decir, le
permite saber qué bit es el primero de cada carácter).
6.1.2 Cables y Conectores
Los dispositivos SATA, tanto de 3,5” como de 2,5”, disponen de un conector macho
con dos segmentos, uno de señal y otro de alimentación, mientras que los controladores
pueden disponer de un conector hembra con los dos segmentos o de un conector macho
con sólo el segmento de señal.
El segmento de señal dispone de 7 contactos, 4 para los dos pares de señal y 3 para
masa. El segmento de alimentación dispone de 15 contactos, 3 para cada alimentación
18
(5V, 12V y 3,3V), uno reservado y el resto para masas. Para permitir la conexión en
caliente, los contactos tienen distintas longitudes para secuenciar la conexión.
Figura 5. Conectores serie
En el caso de conexión directa, el conector del dispositivo se inserta directamente en el
conector hembra de dos segmentos del controlador, lo que proporciona al dispositivo
todos los contactos tanto de señal como de alimentación. Para hacer posible este tipo de
conexión, las posiciones de las señales de transmisión y recepción en el segmento de
señal del controlador están invertidas respecto a las del dispositivo.
En el caso de conexión por cable, el segmento de señal del dispositivo se conecta al
conector macho de señal del controlador mediante un cable de señal SATA, el cual está
formado por dos secciones de cable twinaxial, una para cada par de señal diferencial. La
longitud del cable puede ser de hasta 1 metro y sus dos extremos son simétricos, por lo
que cualquiera de los extremos se puede conectar tanto en el controlador como en el
dispositivo. El conector macho de señal del controlador también tiene invertidas las
19
posiciones de las señales de transmisión y recepción, por lo que el cable de señal no
intercambia las posiciones de los pares. Por otro lado, el segmento de alimentación del
dispositivo se conecta a un cable de alimentación SATA que puede venir directamente
de la fuente de alimentación del equipo o puede terminar en un conector para su
conexión en algún lugar del equipo.
Para facilitar la transición de ATA a SATA, en los dispositivos de 3,5” se permiten
varias configuraciones mixtas de conectores SATA y ATA (denominados conectores
heredados):
• Configuración 35A1: Conector de dos segmentos SATA y ningún conector
heredado
• Configuración 35B1: Conector de dos segmentos SATA y conector heredado de
alimentación y puentes de configuración.
• Configuración 35B2: Conector de señal SATA y conector heredado de
alimentación y puentes de configuración.
• Configuración 35B3: Conector de señal SATA y conector heredado de
alimentación.
• Configuración 35B4: Conector de dos segmentos SATA y conector heredado de
puentes de configuración.
• Configuración 35B5: Conector de dos segmentos SATA y conector heredado de
alimentación.
• Configuración 35C1: Conector de señal SATA, conector heredado de señal ATA
y conector heredado de alimentación
Los dispositivos de 2,5” sólo disponen del conector de dos segmentos SATA:
6.1.3 Señales OOB (Out Of Band)
Las señales OOB (Out of Band) son unos patrones de señales de baja velocidad que no
aparecen durante las transmisiones, y que sólo se utilizan durante la inicialización del
enlace. Consisten en ciclos de duraciones predefinidas de reposo y de transmisión de
unas determinadas secuencias de señal (primitivas ALIGN, que se describen más
adelante). La transmisión de las primitivas ALIGN se usa sólo para producir una
envolvente, de forma de el receptor distingue las distintas señales OOB por la duración
del intervalo de reposo que hay entre las consecutivas secuencias de señal (la duración
de las secuencias de señal no se utiliza para distinguir las distintas señales OOB).
SATA define dos señales OOB:
• COMRESET / COMINIT
El controlador la envía para transmitir la señal COMRESET, que origina una
inicialización hardware en el dispositivo. El dispositivo la envía para transmitir la señal
COMINIT, para solicitar al controlador la inicialización del enlace (negociación de la
velocidad y comienzo de la comunicación).
20
•
COMWAKE
Esta señal la puede enviar tanto el controlador como el dispositivo, y se utiliza para
despertar al otro Phy desde un estado de ahorro de energía, y también durante el proceso
de inicialización del enlace.
6.1.4 Secuencia de inicialización del phy
La secuencia de inicialización del phy consiste en una secuencia de señales OOB
seguida de una secuencia de negociación de velocidad.
La secuencia OOB puede comenzarla el controlador con la transmisión de
COMRESET, o puede comenzarla el dispositivo con la transmisión de COMINIT. La
secuencia también incluye un intercambio de señales COMWAKE y una fase de
calibración de la impedancia de salida del transmisor del controlador (y opcionalmente
también del dispositivo) para adaptarse a la impedancia de la interconexión (ya que
puede ser directa o por cable).
La fase de negociación de velocidad comienza entonces con la transmisión por parte del
dispositivo de primitivas ALIGN a la velocidad más alta que soporte (las primitivas se
describen más adelante), mientras que el controlador transmite un determinado dato a la
velocidad más baja que soporte. Si el controlador soporta la velocidad a la que el
dispositivo está transmitiendo las primitivas ALIGN, entonces pasa a transmitir también
primitivas ALIGN a dicha velocidad, lo que el dispositivo interpreta como que la
velocidad de enlace es correcta.
Si el dispositivo no recibe primitivas ALIGN a esa velocidad en un intervalo de tiempo,
entiende que el controlador no soporta esa velocidad de enlace y comienza un nuevo
proceso a la velocidad inmediatamente más baja que soporte.
6.2 El nivel de Enlace
El nivel de enlace define el uso de la codificación 8b/10b, el uso de las distintas
Primitivas y algunos otros detalles como los relativos al código de detección de errores
(CRC) y a la aleatorización de datos (scrambling), para distribuir la emisión de energía
electromagnética cuando se transmiten secuencias repetitivas de caracteres.
6.2.1 Codificación 8b10b: Caracteres de datos, caracteres de control y patrón Coma
La codificación 8b10b es muy utilizada actualmente en transmisión serie a velocidades
cercanas y superiores al Gbps. Es la codificación utilizada por Fibre Channel (1 y 2
Gbps), posteriormente adoptada por Gigabit Ethernet (1 Gbps), y actualmente en uso
por SAS y SATA (1,5 y 3 Gbps), FireWire 800 (800 Mbps), así como por InfiniBand
(2,5 Gbps).
21
La codificación tiene las siguientes funciones:
• Asegurar suficientes transiciones en la línea como para que el receptor pueda
recuperar el reloj y así pueda recibir adecuadamente la secuencia de bits,
• Incrementar en gran medida las posibilidades de detección de errores simples y
múltiples que puedan ocurrir durante la transmisión, y
• Permitir la transmisión de caracteres especiales que contienen un patrón
fácilmente reconocible por el receptor (denominado patrón Coma), que le
permite alinear palabras en la secuencia de bits que recibe (es decir, le permite
conocer qué bit es el primero de una palabra).
La codificación 8b10b consiste en sustituir cada octeto (8 bits) por un código de 10 bits
antes de su transmisión. De todos los posibles códigos de 10 bits (en total 2^10 = 1024)
sólo se utilizan 512 para codificar todos los posibles caracteres de datos (que en total
pueden ser 2^8 = 256), y unos pocos códigos más para codificar una serie de caracteres
de control (el motivo de utilizar el doble de códigos que de caracteres a codificar se
explica más adelante).
Todos los caracteres que se transmiten en SATA se agrupan en una secuencia de 4
octetos denominada dword. El primer carácter de una dword puede ser un carácter de
dato, en cuyo caso la dword está formada por 4 caracteres de dato (y la información que
transporta es por lo tanto un dato de 32 bits), o puede ser un carácter de control, en cuyo
caso la dword está formada por el carácter de control y 3 caracteres de datos (la dword
en este caso se denomina Primitiva, y transporta información de control).
La codificación 8b10b utiliza un formato particular para expresar los caracteres de 8
bits:
• Zxx.y
Por un lado la letra Z identifica si el carácter es un dato (en cuyo caso Z = D), o si es un
carácter de control (en cuyo caso Z = K). Por otro lado, xx es el valor decimal de los
bits 4:0 mientras que y es el valor decimal de los bits 7:5 del carácter. Entonces Dxx.y
expresa cualquiera de los 256 posibles caracteres de datos, mientras que Kxx.y expresa
cualquiera de los caracteres de control válidos (la codificación 8b10b sólo permite 12
códigos de control válidos).
El codificador 8b10b convierte cada carácter Dxx.y y Kxx.y a su correspondiente
código de 10 bits, teniendo en cuenta que cada carácter puede codificarse mediante dos
códigos distintos, dependiendo del valor de un parámetro que se denomina disparidad
(por eso se necesitan el doble de códigos que de caracteres a codificar).
El concepto de disparidad es el siguiente: de todos los posibles códigos de 10 bits, el
sistema 8b10b sólo utiliza aquellos que tienen:
• 5 unos y 5 ceros. En este caso se dice que el código tiene disparidad neutra,
• 6 unos y 4 ceros. En este caso el código tiene disparidad positiva, y
• 4 unos y 6 ceros. En este caso el código tiene disparidad negativa.
22
La idea es que cada código que se transmita cancele la disparidad producida por el
código anterior, de forma que el nivel de continua de la señal eléctrica es nulo
permanentemente.
De los 12 posibles caracteres de control permitidos por el sistema 8b10b, SATA utiliza
dos: el K28.3 y el K28.5.
De los 12 posibles caracteres de control permitidos por el sistema 8b10b, hay 3 cuyos
códigos de 10 bits contienen en sus 7 primeros bits un patrón especial que se denomina
Coma, que consiste en 2 bits a un valor seguidos por 5 bits al valor contrario. Los phys
utilizan este patrón especial para conseguir la sincronización (alineación) a nivel de
dword, es decir, para conocer qué bit es el primero de una dword (una vez conseguida la
alineación, el phy sabe que cada 40 bits comienza una nueva dword). De los dos
caracteres utilizados por SATA, sólo el K28.5 contiene el patrón Coma, por lo que este
carácter sólo se utiliza en la primitiva ALIGN, mientras que el carácter K28.3 se utiliza
en todas las demás primitivas. De esta manera los Phys alinean los caracteres sólo
cuando reciben la primitiva ALIGN.
6.2.2 Primitivas y Tramas
Las primitivas y las tramas son las dos estructuras utilizadas para intercambiar
información entre el controlador y el dispositivo.
Las primitivas constan de una sola dword que comienza por un carácter de control, y es
la forma más simple de intercambio de información. Las primitivas proporcionan
información de control de bajo nivel.
Las tramas son secuencias de dwords que transportan información. Las tramas siempre
comienzan con la primitiva SOF (Start of Frame) y terminan con la primitiva EOF (End
of Frame). La última dword (que no sea una primitiva) anterior a la primitiva EOF es el
CRC de la trama, mientras que el resto de la trama (es decir, las dwords entre el SOF y
el CRC) es la información propiamente dicha transportada en la trama y se denomina
FIS (Frame Information Structure). Es posible la transmisión de ciertas primitivas de
control de flujo en el interior de la trama (HOLD, HOLDA y CONT).
Las primitivas definidas en SATA son:
•
ALIGN
Se envía para que el nivel físico del receptor reajuste sus operaciones internas (entre
otras, alinear la secuencia de bits de entrada en dwords de la manera correcta, a partir
del patrón Coma).
•
CONT
Se utiliza para eliminar secuencias repetitivas de la misma primitiva, con el objetivo de
reducir el nivel de emisión electromagnética. Cuando hay que enviar repetidamente la
misma primitiva, lo que se hace es enviar la primitiva seguida de la primitiva CONT y
seguida de dwords aleatorias. El receptor interpreta como si estuviera recibiendo
23
repetidamente la primitiva recibida anteriormente a la primitiva CONT, en tanto no
reciba una nueva primitiva.
•
DMAT
La envía el receptor de una trama para solicitar al transmisor que aborte una
transferencia de datos por DMA.
•
EOF
Se usa para indicar el final de una trama.
•
HOLD
El transmisor la envía dentro de una trama en puesto de una dword de dato cuando no
tiene una dword de dato preparada para su transmisión (underrun), y el receptor la envía
para indicar que no puede recibir todavía una nueva dword de dato (overrun).
•
HOLDA
Se envía en respuesta a una primitiva HOLD, y se transmite siempre que se esté
recibiendo
HOLD.
•
PMACK
Se envía en respuesta a una primitiva PMREQ_S o PMREQ_P, y se transmite cuando el
receptor está preparado para entrar en el modo de ahorro de energía solicitado.
•
PMNAK
Se envía en respuesta a una primitiva PMREQ_S o PMREQ_P, y se transmite cuando el
receptor no está preparado para entrar en el modo de ahorro de energía solicitado o no lo
soporta.
•
PMREQ_P
Se envía para solicitar la entrada en el modo de ahorro de energía parcial.
•
PMREQ_S
Se envía para solicitar la entrada en el modo de ahorro de energía total (denominado
Slumber).
•
R_ERR
La envía el receptor de una trama en respuesta a la primitiva WTRM para indicar que se
ha detectado un error en la trama recibida.
•
R_IP
La envía el receptor de una trama en respuesta a la recepción de cada dword de dato.
•
R_OK
24
La envía el receptor de una trama en respuesta a la primitiva WTRM para indicar que no
se ha detectado ningún error en la trama recibida.
•
R_RDY
Se envía en respuesta a una primitiva X_RDY para indicar que se está preparado para
recibir una trama.
•
SOF
Se usa para indicar el principio de una trama.
•
SYNC
Se usa cuando no hay tramas ni primitivas que enviar (el enlace está desocupado).
•
WTRM
La envía el transmisor de una trama tras el EOF mientras espera que el receptor de la
trama envíe el estado de la recepción (R_ERR o R_OK).
•
X_RDY
Se envía para indicar que hay una trama preparada para su transmisión. La trama no se
envía hasta que no se reciba la primitiva R_RDY.
6.3 El nivel de Transporte
6.3.1 Modos de transferencia
Los dispositivos SATA pueden transferir información principalmente empleando dos
métodos: PIO y DMA.
El modo PIO (Programmed I/O) depende del procesador para efectuar el trasiego de
datos. A nivel de rendimiento no hay mayor problema, ya que los micros actuales tienen
la suficiente capacidad para gestionar estas operaciones y alternarlas con otras, por
supuesto.
El otro método es el DMA, así la CPU se desentiende de la transferencia, teniendo ésta
lugar por mediación de un chip DMA dedicado. La variante de la transferencia DMA
usada actualmente en los discos duros es la BusMaster DMA. Esta modalidad
aprovecha las ventajas de los chipsets de las placas base, cada vez más optimizados para
estas labores (de acceso directo a memoria). Además de liberar al procesador, puede
obtener por parte de éste un control casi total, de forma que la información sea
transferida con la máxima prioridad.
25
6.3.1.1 Programmed I/O
El método más antiguo de transferir datos en la interfaz IDE/ATA es el empleo del
modo PIO (Programmed I/O). Esta técnica se basa en que la CPU del sistema y el
hardware de apoyo controlen directamente la transferencia de datos entre el sistema y el
disco duro. Existen varias velocidades de transferencia utilizando este método, estas
variaciones se llaman modos de entrada - salida programados, o más comúnmente,
modos de PIO.
Durante mediados de los años 90, la entrada - salida programada era el único camino
que la mayor parte de sistemas utilizaban para el acceso a discos duros IDE/ATA. Tres
modos de velocidad fueron definidos en las normas ATA aparte de otros dos que fueron
añadidos más tarde. A continuación la tabla nos muestra los cinco diferentes modos de
PIO, con el tiempo de ciclo para cada transferencia y el rendimiento correspondiente del
modo:
Figura 6. Diferentes modos PIO
Algunas cosas sobre esta tabla deben ser mencionadas. Ante todo, los modos PIO son
definidos en función de su tiempo de ciclo, representando cuantos nanosegundos que
este necesita para efectuar una transferencia. El índice de transferencia máxima es el
recíproco del tiempo de ciclo, es el doble porque la interfaz es dos octetos (16 bits).
También, es necesario destacar la ausencia en la tabla del supuesto " modo 5 de PIO ",
Este no existe y nunca fue puesto en práctica en ningún disco duro. Al parecer, una vez
alguna discusión ocurrió sobre la creación de un modo PIO más rápido, que
provisionalmente llamaron " el modo 5 de PIO". Este modo debía soportar una
velocidad de transferencia de 22.2 MB/S, pero nunca fue puesto en práctica
(probablemente porque el modo mucho más rápido Ultra DMA de 33 MB/S 2 lo
superaba mucho). Algunos fabricantes de placa madre se encargaron de dar apoyo a este
modo propuesto para sus programas de BIOS pero al final no tuvieron éxito.
Obviamente, los modos más rápidos son mejores, porque proporcionan una velocidad
de transferencia de la interfaz teóricamente más alta. Esta representa la velocidad de
transferencia de datos alrededor del dispositivo. Hay que recordar que es la velocidad de
la interfaz y no necesariamente la velocidad de transferencia soportada por el disco, que
es casi siempre más lento (y debería ser). Desde luego hoy todos los nuevos discos
soportan velocidades de transferencia superiores a la máxima velocidad que el mejor
modo PIO puede alcanzar, una de la razones porque PIO ha perdido importancia.
26
Como ya se ha mencionado, la I/O programadas se realiza por la CPU, el procesador del
sistema es el responsable de ejecutar las instrucciones que transfieren los datos al disco
y desde él, usando posiciones de entrada - salida especiales. Estos trabajos técnicos son
ideales para dispositivos lentos como teclados y módems, pero para dispositivos de
funcionamiento similar a los discos duros causa problemas de funcionamiento. PIO no
es lo único que implica una atención elevada, la CPU está "distraída" con su trabajo
ordinario hasta que un disco duro necesita ser leído o escrito. Esto quiere decir que la
utilización de PIO es inmejorable para funcionamientos ligeros y tascas simples. Pero
en el mismo tiempo quiere decir que con más transferencias de datos, más atascada está
la CPU. Como las tasas de transferencia de los discos duros siguen aumentando, la
carga sobre la CPU se hace cada vez mayor. Esta es otra razón clave por la cual los
modos PIO son menos usados en nuevos sistemas, estos modos han sido substituidos
por modos DMA, y más tarde por Ultra DMA.
Existen dos canales IDE, cada canal admite el empleo de dos dispositivos, designados
como el máster y el esclavo. Los sistemas modernos permiten que el dispositivo máster
y el esclavo corran en modos PIO diferentes sobre el mismo canal, esto se llama
independent device timing y es una función del chipset y la BIOS. Si no se suporta esta
característica, ambos dispositivos pueden ser limitados al modo PIO más rápido del
dispositivo más lento de los dos, pero esto no es un gran problema desde la segunda
mitad de los años 90.
Los modos PIO no requieren ningún driver especial en circunstancias normales, la
BIOS del sistema contiene toda la información necesaria para un correcto
funcionamiento de estos modos. Esta compatibilidad universal, pese su simplicidad
conceptual, es la manera tradicional usada por defecto en la mayoría de discos. Hoy en
día, sin embargo, PIO se sigue usando para discos modernos, que usan Ultra DMA para
disminuir la carga sobre la CPU y permitir disfrutar de un rendimiento más alto. La
compatibilidad de los modos PIO es todavía universal en casi todos los sistemas y
discos actuales. Se usa, por ejemplo, como último recurso cuando el driver o el software
presentan problemas con el acceso vía Ultra DMA.
6.3.1.2 DMA
Como ya se ha descrito en el apartado anterior (programmed I/O). Aquel método de
transferencia de datos entre el disco duro y el sistema tiene defectos muy serios puesto
que requiere el cuidado y la atención de la CPU del sistema. Claramente, una mejor
solución es dejar la CPU fuera del escenario completamente, y hacer que el disco duro y
la memoria del sistema se comuniquen directamente. El acceso directo a memoria o
DMA es el término genérico que se refiere a un protocolo de transferencia donde un
dispositivo periférico transfiere información directamente a memoria o desde la misma,
sin que se necesite una intervención del procesador de sistema para realizar la
transacción. DMA ha sido usado en el PC durante años con el bús ISA, para
dispositivos como las tarjetas de sonido y la interfaz del disquete. El DMA
convencional usa los canales de DMA regulares que son un recurso del sistema
estándar.
27
Varios modos DMA diferentes han sido definidos para la interfaz IDE/ATA, están
agrupados en dos categorías. El primer juego de modos incluye modos DMA de un solo
Word. Cuando se usan estos modos, cada transferencia es de un solo Word de datos (un
Word es el término técnico de dos Bytes, o bien 16 bits de memoria). Hay tres modos
DMA de un solo Word.
Figura 7. Diferentes modos DMA Single Word
Como hablé en el apartado de PIO, la tasa de transferencia máxima es doble del tiempo
de ciclo específico para cada modo. Obviamente, estas velocidades de transferencia no
son impresionantes para las especificaciones de hoy en día. Lo que es realmente claro es
que realizar transferencias de una sola palabra cada vez es horriblemente ineficaz. Por
eso, los modos Single Word DMA fueron rápidamente sustituidos por los modos DMA
Multiword. Como el nombre indica, con estos modos "una serie" de transferencias
ocurre una tras otro, un Word después de otro, evitando hacer, por separado, una
transferencia para cada palabra. Aquí están los modos de transferencia DMA
MultiWord:
Figura 8. Diferentes modos DMA Multiword
Puesto que el DMA Multiword es más eficiente, y también tiene velocidades de
transferencia más altas, los modos Single Word DMA fueron rápidamente abandonados
después de que el estándar ATA-2 fuera extensamente adoptado – estos modos fueron
quitados de las normas ATA en las especificaciones del ATA-3. Entonces todos los
28
accesos vía DMA hoy en día (incluyendo Ultra DMA) son en realidad de MultiWord. El
término "MultiWord" se da por sabido en casi todos los estándares del Serial y Parallel
ATA.
Otra característica importante del DMA es que hay dos modos diferentes de hacer
transferencias. DMA convencional es lo que llaman “tercera parte” del DMA, que
quiere decir que los controladores del DMA sobre la placa madre coordinan las
transferencias de DMA. ("la tercera parte" es el controlador DMA.) Lamentablemente,
estos controladores DMA eran viejos y muy lentos – se puede decir que no han sido
modificados durante mucho tiempo. Estos dispositivos estaban bastante ligados a los
viejos los buses de ISA, que se dejaron de usar para interfaces del disco duro por
motivos de rendimiento. Cuando los modos 1 y 2 del DMA Multiword comenzaron a
hacerse populares, se hizo el empleo del bús PCI de alta velocidad para tarjetas de
controladores IDE/ATA. En aquel punto, el viejo modo de hacer transferencias vía
DMA tuvo que ser cambiado.
Los Discos duros modernos usan “primera parte” de DMA transferencias. El término
"primera parte " quiere decir que el dispositivo periférico hace, él mismo, el trabajo de
transferir datos de la memoria y hacia ella, sin el controlador externo del DMA.
También se llama Bus Mastering, porque cuando dichas transferencias ocurren el
dispositivo se hace "amo del bús”. Bus Mastering permite al disco duro y la memoria
trabajar sin depender de los viejos controladores DMA incorporados en el sistema, o de
cualquier apoyo de la CPU. Esto requiere el empleo del bús PCI - viejos buses como
MCA también eran compatibles con el Bus Mastering, pero no son de uso abundante.
En resumen, este método permite que la transferencia de datos entre la memoria del
sistema y el disco duro sea más eficiente y también permite bajar la carga sobre la
unidad central de proceso durante las transferencias.
Curiosamente, a pesar de las ventajas del Bus Mastering, el empleo del modo 2 del busmastering multiword DMA nunca ganó realmente popularidad por varios motivos. El
más importante era el pobre apoyo a esta tecnología en los primeros dos años. La
Utilización de PIO no requería ningún trabajo y era muy simple. También, DMA no fue
compatible con la primera versión de Windows 95, entonces se tuvieron que utilizar
Drivers especiales. Los problemas con la implementación del Bus Mastering DMA en
los sistemas entre 1996 y 1998 eran numerosos: dificultades con los Drivers, el
software operaba correctamente, los lectores de CD-ROM no eran compatibles con los
Drivers, etcétera. Ante estos problemas, DMA no marcó la diferencia como ya se
esperaba. Es seguro que la reducción de uso de la CPU estaba muy bien, pero ya que la
velocidad máxima del mejor modo DMA era la misma que la del modo PIO más alto
(16.7 MB/S) no quedaba claro que DMA ofrecía unas ventajas importantes en
comparación con PIO. Dadas las pequeñas diferencias, muchos programadores
estuvieron lejos de usar DMA, para evitar las incompatibilidades y problemas de
estabilidad que muy a menudo presentaba este último.
Bus Mastering DMA finalmente entró en crisis cuando la industria siguió adelante con
los proyectos de Ultra DMA. Cuando Ultra DMA/33 duplicó la velocidad de
transferencia de la interfaz, DMA tuvo una ventaja de velocidad clara sobre PIO aparte
de otras mejoras de eficacia. La compatibilidad con el DMA se planteó de forma
correcta en Windows 9x, y la mayor parte de los problemas de los viejos Drivers fueron
eliminados. Hoy en día, el uso del Ultra DMA es un estándar en la industria.
29
6.3.1.3 ULTRA DMA
Desde luego, los discos duros se hacen más y más rápido, y la velocidad máxima del
modo 2 del DMA Multiword, 16.7 MB/S, pronto se hizo insuficiente para los discos
más rápidos. Sin embargo, los ingenieros que trabajaron para acelerar la interfaz
descubrieron que no era ninguna tarea simple. La interfaz fue diseñada para
transferencias de datos lentas - aproximadamente 5 MB/S. El aumento de la velocidad
de la interfaz (reduciendo el tiempo de ciclo) causó todos los tipos de problemas
relacionados con la interferencia. Para hacer la interfaz más rápida, unas medidas
diferentes tuvieron que ser tomadas: mejora de la eficacia de la interfaz. El resultado era
la creación de un nuevo tipo de modos de transferencia DMA, que se llamaron modos
Ultra DMA.
El avance tecnológico clave introducido en Ultra DMA era el double transition
clocking. Antes del Ultra DMA, una transferencia de datos ocurría en cada ciclo de
reloj, provocado por el pulso del reloj de la interfaz (o el “Strobe”). Con Ultra DMA, los
datos se transfieren tanto si esta a 1 o a 0 el reloj. El Doble cronometrado de las
transiciones, con algunos otros cambios menos importantes hechos, para mejorar la
eficacia, basándose en la técnica señalada, permitieron que en el rendimiento fuera
duplicado para cualquier velocidad de reloj.
Para mejorar la integridad de esta interfaz prácticamente más rápido, Ultra DMA
también introdujo el cyclical redundancy checking o CRC en la interfaz. El dispositivo
que envía los datos usa el algoritmo CRC para calcular la información redundante de
cada bloque de datos enviados en la interfaz. Este " código CRC" se envía con los datos.
En el otro extremo de la interfaz, el dispositivo que recibe los datos hace el mismo
cálculo CRC y compara el resultado con los datos que el remitente entrega. Si la
información no cuadra, esto quiere decir que los datos fueron corrompidos de algún
modo y el bloque de datos se elimina. (CRC es similar en concepto y operación al modo
de comprobación de errores de la memoria del sistema.) Si los errores ocurren con
frecuencia, el sistema puede determinar si hay problemas de hardware y así baja a un
modo más lento de Ultra DMA, o bien desactiva del todo estos modos.
La primera puesta en práctica del Ultra DMA fue especificada en el estándar
ATA/ATAPI-4 que incluía tres modos Ultra DMA, que proporcionaban hasta 33 MB/S
de rendimiento. Más tarde, se han ido añadiendo modos más rápidos del Ultra DMA.
Esta tabla muestra todos los modos actuales del UDMA, con sus tiempos de ciclo y
tasas de transferencia máximas:
Ultra DMA
Mode
Cycle Time
(nanoseconds)
Maximum Transfer
Rate (MB/s)
Defining Standard
Mode 0
240
16.7
ATA/ATAPI-4
Mode 1
160
25.0
ATA/ATAPI-4
30
Mode 2
120
33.3
ATA/ATAPI-4
Mode 3
90
44.4
ATA/ATAPI-5
Mode 4
60
66.7
ATA/ATAPI-5
Mode 5
40
100.0
ATA/ATAPI-6
Mode 6
15
133
ATA/ATAPI-7
(SATA 1.0)
Figura 9. Diferentes modos Ultra DMA
El tiempo de ciclo muestra la velocidad del reloj de la interfaz, la frecuencia del reloj es
la inversa de este número. La tasa de transferencia máxima es cuatro veces el inverso
del tiempo de ciclo - la doble transición que cronometra el medio cada ciclo tiene dos
transferencias, y cada transferencia mueve dos Bytes.
Double transition clocking es el que permite al modo 2 del UDMA tener una velocidad
de transferencia máxima de 33.3 MB/S, a pesar del hecho de tener un tiempo de ciclo
idéntico al modo 2 del MultiWord DMA, que alcanza la mitad de esta cifra. Ahora,
usted puede preguntarse: ¿si ellos usaron el Double transition clocking para alcanzar los
33.3 MB/S, cómo consiguieron los 66 MB/S, los 100 MB/S, y luego los 133 MB/S?
Bien, lo que se hizo realmente es acelerar la interfaz después. Pero el empleo del
Double transition clocking les permitió quedarse en la mitad de la velocidad que
realmente necesitaban. Sin este método, el modo 5, por ejemplo, del Ultra DMA habría
requerido un tiempo de ciclo de 20 nanosegundos en vez de 40, haciendo la puesta en
marcha mucho más difícil.
Incluso con las ventajas del Double transition clocking, funcionando por encima de los
33 MB/S finalmente se excedieron las capacidades del cable 40-conductor standard
IDE. Para usar modos superiores al 2 se requería un cable IDE especial 80-conductor.
Este cable usa los mismos 40 pins que los viejos cables, pero añade 40 líneas de tierra
entre las 40 señales originales para separarlas y para resolver problemas de corrupción
de datos y interferencias. (El cable de 80 conductores en realidad fue especificado en
ATA/ATAPI-4 con los primeros modos Ultra DMA, pero era "opcional" para los modos
0, 1 y 2.)
Hoy, todos los sistemas modernos que usan discos IDE o SATA deberían usar uno de
los modos Ultra DMA. Hay varios requisitos específicos para trabajar con Ultra DMA:
• Compatibilidad con el disco duro: El disco duro mismo debe ser compatible con
Ultra DMA. Además, el disco debe permitir el modo apropiado del Ultra DMA.
• Compatibilidad con el controlador: se debe usar un controlador capaz de hacer
transferencias Ultra DMA. Este puede ser el controlador de la interfaz
incorporado en la placa madre, o bien uno añadido en la tarjeta de la interfaz.
31
• Compatibilidad con el Sistema operativo: La BIOS y/o el sistema operativo
deben ser compatibles con las transferencias Ultra DMA, y el disco duro debe
ser programado para funcionar en Ultra DMA en el sistema operativo.
• Un cable de 80 conductores: Para modos Ultra DMA superiores al 2, se debe
usar un cable de 80 conductores. Si el sistema no reconoce ningún cable de 80
conductores se desactivan los modos 4,5 y 6 del UDMA.
En los nuevos sistemas hay pocas limitaciones con la compatibilidad del Ultra DMA,
porque el hardware es nuevo y diseñado para funcionar con este modo de tranferencias.
En los sistemas más viejos, la cosa es un poco más compleja. En teoría, los nuevos
discos deben ser compatibles con los controladores más viejos, de tal modo que si
instalamos un disco compatible con Ultra DMA en un PC viejo, esto debe causar que el
sistema funcione con un modo lento como ahora PIO 4. Lamentablemente, ciertas
placas madre no funcionan bien cuando se usa un disco UDMA, y esto puede causar
errores. Una mejora de la BIOS del fabricante de la placa madre es una idea buena, si
somos capaces de hacerlo. Otra solución sería usar una utilidad de software especial
Ultra DMA (dada por el fabricante del disco) para informar el disco duro de que no
tiene que funcionar en modos UDMA. La misma utilidad puede ser usada para permitir
los modos UDMA en discos que están configurados para no usarlos.
6.3.2 Los registros Shadow
Los registros Shadow son registros virtuales emulados en Sata para reflejar el contenido
y el funcionamiento normal de los discos duros. Estos son los mismos que los registros
de entrada y salida de los discos IDE.
El bloque de registros de comando se usa para enviar comandos al dispositivo o bien
para obtener información sobre el estado del mismo. El bloque de registros de Control
se usa para el control de dispositivo y forzar un estado alterno.
A continuación vamos a ver todos estos registros de forma resumida.
32
6.3.2.1 Registro de comandos
Descripción del funcionamiento
Este registro contiene el código del
comando que se enviará al dispositivo.
La ejecución del comando comienza
inmediatamente después de que este
registro se escriba. Las órdenes
ejecutables y los códigos de los
comando
están resumidos en el
apartado Comandos.
Direccionamiento
Este registro es de solo lectura. Si se lee
esta dirección por Host, se lee el
registro de Estado.
Eficacia
El
procesamiento
del
comando
comienza cuando este registro se
escribe. El contenido del bloque de
registros de comando se convierte en los
parámetros de entrada del comando
cuando este registro se escribe. La
escritura de este registro limpia
cualquier interrupción pendiente.
Descripción de los bits:
Para todo los comandos, excepto
“Device Reset”, se debe escribir en este
registro solo cuando los bits de estado
BSY, DRQ y DMACK valen 0. Si
ocurre lo contrario, no se puede saber el
resultado de la operación excepto el
comando “Device Reset”. Si el
dispositivo esta en modo Sleep todos los
comandos se ignoran.
Restricciones de acceso
33
6.3.2.2 Puerto de datos
Descripción del funcionamiento
Direccionamiento
El puerto de datos es de 16 bits de ancho.
Este puerto es de lectura y escritura
En el modo DMA, las escrituras y lecturas
de datos en las dos direcciones (hacia host
o hacia el dispositivo) son una serie de
escrituras o lecturas consecutivas de este
puerto. El resultado de una lectura de este
puerto mientras se escribe o bien de una
escritura mientras se lee es indeterminado.
Eficacia
Descripción de los bits:
Restricciones de acceso
Para todo los comandos, excepto “Device
Reset”, se debe escribir en este registro
solo cuando los bits de estado BSY, DRQ
y DMACK valen 0. Si ocurre lo contrario,
no se puede saber el resultado de la
operación excepto el comando “Device
Reset”. Si el dispositivo esta en modo
Sleep todos los comandos se ignoran.
34
6.3.2.3 Registro de datos
Descripción del funcionamiento
Direccionamiento
El puerto de datos es de 16 bits de ancho.
Si un dispositivo trabaja con el modo PIO
Single Word de 8 bits solo se usa la parte
baja de este registro del DD7 a DD0.
Este registro es de lectura y escritura
En el modo PIO, las escrituras y lecturas
de datos en las dos direcciones (hacia host
o hacia el dispositivo) son una serie de
escrituras y lecturas consecutivas de este
puerto. El resultado de una lectura de este
puerto mientras se escribe o bien de una
escritura mientras se lee es indeterminado.
Eficacia
Descripción de los bits:
Restricciones de acceso
El controlador solo debe usar este registro
cuando el bit de estado DRQ vale 1 y el
bit DMACK vale 0. Los datos de este
registro no son validos cuando el
dispositivo esta en modo Sleep
35
6.3.2.4 Registro del dispositivo
El bit 4, denominado DEV, es el
seleccionador del dispositivo. Los otros
bits dependen del comando. Se
explican en el apartado Comandos
Descripción del funcionamiento
Direccionamiento
Este registro es de lectura y escritura
El bit DEV tiene importancia cuando
se escribe este registro por el Host o
bien cuando el mismo dispositivo
actúa. Los otros bits son parámetros de
entrada cuando se escribe en el registro
de comandos.
Eficacia
Descripción de los bits:
•
DEV: es el selector de dispositivos, 0 selecciona el dispositivo 0 y 1 selecciona el
•
Los bits (3:0) se usan como parte del sector lógico que se quiere especificar. Así se
suman 4 bits a los 24 bits de los registros LBA alto, medio y bajo. Cuando se trata de
direccionamiento 48 bits estos bits se ignoran
dispositivo 1.
Este registro solo se debe escribir
cuando los bits de estado BSY, DRQ y
DMACK están a cero. El contenido de
este registro es válido solo cuando
BSY es 0. También es inválido el
contenido cuando el dispositivo está en
modo Sleep. Se desconoce el resultado
de escritura de este registro cuando los
bits de estado ya mencionados están a
1.
Restricciones de acceso
36
6.3.2.5 Registro de control del dispositivo
Este registro permite al Host hacer un
Software reset del dispositivo conectado y
habilitar o deshabilitar la aserción de la
señal INTRQ por el dispositivo
seleccionado. Cuando el registro de
Control del Dispositivo se escribe, ambos
dispositivos (Master y esclavo) responden
a lo escrito independientemente de cuál es
el dispositivo seleccionado. Cuando el bit
de SRST se pone a uno, ambos
dispositivos siguen el protocolo de reset
del software. El dispositivo debe
responder al bit de SRST cuando en el
modo sleep.
Descripción del funcionamiento
Direccionamiento
Este registro es solo de escritura. Si se lee
en esta dirección, se lee el registro de
estado alternativo.
Eficacia
Este registro solo es eficaz cuando se
escribe.
Descripción de los bits:
•
•
•
•
•
HOB es un bit relacionado con el direccionamiento 48 bit
Los bits (6:3) están reservados
SRST es el bit del software reset
nIEN controla la señal INTRQ. Cero habilita y uno deshabilita
El bit debe estar a cero.
Este registro solo se debe escribir cuando
el bit DMACK no está activado.
Restricciones de acceso
37
6.3.2.6 Registro de errores
Para todos los comandos, excepto los
comandos
EXECUTE
DEVICE
DIAGNOSTIC y DEVICE RESET, el
contenido de este registro es válido
cuando está activado el bit ERR del
registro de estado. Después de un
encendido o un comando de los citados
anteriormente este registro contiene un
código de diagnostico.
Descripción del funcionamiento
Este registro es solo de lectura. Si se
escribe por el controlador, se escribe el
registro características.
Direccionamiento
Eficacia
ninguna
Descripción de los bits:
•
•
ABRT (comando abortado) este bit se pone a uno cuando ya se ha abortado el
comando mandado porque el código o los parámetros no son válidos, hay problemas
de compatibilidad con el comando o bien no se cumplen los prerrequisitos para ejecutar
el comando.
El resto de bits depende del comando.
El contenido de este registro es válido
cuando los bits de estado BSY y DRQ
están a cero y el bit ERR o SE está a
uno.
También es válido después de un Poweron, un Hardware o Software reset, o
después de la conclusión de la ejecución
de los comandos EXECUTE DEVICE
DIAGNOSTICS o DEVICE RESET.
El contenido no es válido cuando el
dispositivo está en modo sleep
Restricciones de acceso
38
6.3.2.7 Registro de características
Descripción del funcionamiento
El contenido de este registro depende del
comando. Se explica en el apartado
Comandos.
Direccionamiento
Este registro es solo de escritura. Si se lee
por el controlador, se lee el registro de
errores.
Eficacia
El contenido de este registro se convierte
en un parámetro de entrada cuando se
escribe en el registro de comandos
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
Este registro se debe escribir solo cuando
BSY y DRQ están a cero y DMACK esta
desactivado. Si se escribe mientras los bits
de estado BSY y DRQ están a uno, el
resultado es indeterminado.
39
6.3.2.8 LBA alto
Descripción del funcionamiento
Direccionamiento
Eficacia
Este registro contiene una parte del valor
de sector lógico sobre el cual se desea
operar. Este registro depende del comando
enviado al disco.
Este registro es de escritura y lectura.
El contenido de este registro se convierte
en un parámetro de entrada cuando se
escribe en el registro de comandos
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
Este registro se debe escribir solo cuando
BSY y DRQ están a cero y DMACK esta
desactivado. Si se escribe mientras los bits
de estado BSY y DRQ están a uno, el
resultado es indeterminado. El contenido
de este registro no es válido cuando el
disco está en modo Sleep.
40
6.3.2.9 LBA bajo
Descripción del funcionamiento
Direccionamiento
Eficacia
Este registro contiene una parte del valor
de sector lógico sobre el cual se desea
operar. Este registro depende del comando
enviado al disco.
Este registro es de escritura y lectura.
El contenido de este registro se convierte
en un parámetro de entrada cuando se
escribe en el registro de comandos
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
Este registro se debe escribir solo cuando
BSY y DRQ están a cero y DMACK esta
desactivado. Si se escribe mientras los bits
de estado BSY y DRQ están a uno, el
resultado es indeterminado. El contenido
de este registro no es válido cuando el
disco está en modo Sleep.
41
6.3.2.10 LBA medio
Descripción del funcionamiento
Direccionamiento
Eficacia
Este registro contiene una parte del valor
de sector lógico sobre el cual se desea
operar. Este registro depende del comando
enviado al disco.
Este registro es de escritura y lectura.
El contenido de este registro se convierte
en un parámetro de entrada cuando se
escribe en el registro de comandos
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
Este registro se debe escribir solo cuando
BSY y DRQ están a cero y DMACK esta
desactivado. Si se escribe mientras los bits
de estado BSY y DRQ están a uno, el
resultado es indeterminado. El contenido
de este registro no es válido cuando el
disco está en modo Sleep.
42
6.3.2.11 Registro de cuenta de sectores
Descripción del funcionamiento
Direccionamiento
Eficacia
Este registro contiene el número de
sectores sobre los cuales se desea operar.
Este registro depende del comando
enviado al disco.
Este registro es de escritura y lectura.
El contenido de este registro se convierte
en un parámetro de entrada cuando se
escribe en el registro de comandos
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
Este registro se debe escribir solo cuando
BSY y DRQ están a cero y DMACK esta
desactivado. Si se escribe mientras los bits
de estado BSY y DRQ están a uno, el
resultado es indeterminado. El contenido
de este registro no es válido cuando el
disco está en modo Sleep.
43
6.3.2.12 Registro de estado
Descripción del funcionamiento
Este registro contiene información sobre
el estado del disco. El contenido de este
registro se actualiza constantemente para
reflejar el estado del dispositivo.
Direccionamiento
Este registro es solo de lectura. Si
escribimos en esta dirección, escribimos
en el registro de comandos
Eficacia
Leer este registro mientras hay una
interrupción pendiente, elimina dicha
interrupción. El controlador no debe leer
este registro cuando se ejecuta una
interrupción porque puede ser que no la
reconozca.
Descripción de los bits:
•
•
•
•
•
BSY: Este bit se pone a 1 cuando el dispositivo está ocupado. Cuando se escribe el
registro de comandos y, obviamente, se ejecuta el comando, este bit o bien el DRQ se
tiene que poner a 1 hasta que se cumpla la operación.
DRDY: Este bit se pone a 1 cuando el disco está preparado para recibir comandos o
cuando se cumpla la ejecución de un comando.
DF: Este bit se pone a uno cuando hay algo que impide que el comando se ejecute
correctamente y el defecto no está especificado en el registro de errores.
DRQ: Este bit indica que el dispositivo está preparado para hacer transferencias entre
el Host y el disco. Este bit se pone a 1 cuando los datos están preparados para ser
transferidos. Cuando se cumpla la transferencia, este bit se pone a 0.
ERR: Indica que un cierto error ha ocurrido. Cuando este bit se pone a uno el
contenido del registro de errores es válido.
Restricciones de acceso
El contenido de este registro no es válido
cuando BSY está a 1 o bien cuando el
dispositivo está en modo Sleep
44
6.3.2.13 Registro de estado alternativo
Descripción del funcionamiento
Este registro contiene la misma
información que el registro de estado. La
descripción de los bits de este registro esta
en el apartado anterior.
Direccionamiento
Este registro es solo de lectura. Cuando se
escribe este registro por el controlador, se
escribe el registro de comandos del
dispositivo.
Eficacia
Una lectura a este registro no debe
eliminar una interrupción pendiente.
Dirección
• DA: Device address
• CS: Chip select
Restricciones de acceso
El contenido de este registro no es válido
cuando BSY está a 1 o bien cuando el
dispositivo está en modo Sleep
45
6.3.3 FIS (Frame Information Structure)
El nivel de transporte construye las FIS (Frame Information Structure) que se van a
transmitir dentro de las tramas y comprueba el contenido de las FIS de las tramas que se
reciben.
El tipo de la FIS se indica en el primer octeto de la primera dword de la FIS, el cual
indica también de paso la longitud y el formato del contenido de la FIS.
•
FIS Registro – Controlador a Dispositivo
Esta FIS la envía el controlador para transferir al dispositivo el contenido del bloque de
registros shadow. Un bit de la FIS indica si la transferencia es a consecuencia de una
escritura en el registro de Comando o en el registro de Control. El dispositivo actualiza
su bloque de registros y ejecuta el comando o la función de control recibida.
Este es el mecanismo por el cual el software heredado envía comandos al dispositivo.
•
FIS Registro – Dispositivo a Controlador
Esta FIS la envía el dispositivo para transferir al controlador el contenido de su bloque
de registros. El controlador actualiza su bloque de registros shadow. Un bit de la FIS
indica si el controlador debe activar la línea de interrupción.
Este es el mecanismo por el cual el dispositivo indica el estado de terminación de un
comando.
•
FIS Set Device Bits – Dispositivo a Controlador
Esta FIS la envía el dispositivo para transferir el contenido de ciertos bits al bloque de
registros shadow del controlador, sobre los que el dispositivo tiene acceso exclusivo de
escritura. Estos son los 8 bits del registro de Error y 6 bits del registro de Estado (todos
excepto los bits DRQ y BSY).
•
FIS DMA Activate – Dispositivo a Controlador
Esta FIS la envía el dispositivo para indicar al controlador que está preparado para
recibir una FIS de datos como consecuencia de la ejecución de un comando de escritura
por DMA. Si el controlador necesita enviar varias FIS de datos para completar la
transferencia, el dispositivo envía una FIS DMA Activate por cada FIS de datos que
deba recibir.
•
FIS DMA Setup – Dispositivo a Controlador o Controlador a Dispositivo
(bidireccional)
Esta FIS la puede enviar el dispositivo o el controlador para solicitar al otro que
configure su canal de DMA para proceder con una o más transferencias de datos.
Este es el mecanismo para iniciar una transferencia por el método de First-Party DMA.
Es un nuevo método de transferencias en SATA que no soportan los dispositivos ni el
software heredado, en el cual el propio dispositivo SATA gestiona el canal de DMA
46
para acceso directo a la memoria del sistema. El mecanismo es más eficiente que los
mecanismos DMA heredados (Multiword DMA y UDMA).
•
FIS BIST Activate – Bidireccional
Esta FIS la puede enviar el dispositivo o el controlador para solicitar al otro que se
configure en un modo concreto de test (BIST = Built-In Self Test).
•
FIS PIO Setup – Dispositivo a Controlador
Esta FIS la envía el dispositivo para indicar al controlador toda la información necesaria
para la gestión de una transferencia de datos en modo PIO. Si son necesarias varias FIS
de datos para completar la transferencia, el dispositivo envía una FIS PIO Setup por
cada FIS de datos que se necesite transmitir.
•
FIS Dato – Controlador a Dispositivo o Dispositivo a Controlador (bidireccional)
Esta FIS es la utilizada para transferir los datos como consecuencia de la ejecución de
un comando de lectura o escritura en modo PIO, DMA o First-Party DMA. El
dispositivo la usa para enviar datos al controlador (lectura) y el controlador para enviar
datos al dispositivo (escritura).
La longitud máxima de los datos es de 2,048 dwords, (8,192 bytes o 16 sectores de 512
bytes).
6.3.4 Nuevo bloque de registros SATA
Los controladores SATA disponen de un bloque de registros adicional e independiente
del bloque de registros estándar ATA, para permitir la gestión de las nuevas
posibilidades exclusivas de SATA. Este nuevo bloque se denomina SATA SCRs (Status
and Control Registers), y están organizados en 16 posiciones consecutivas de 32 bits.
Los programas heredados no hacen uso de este nuevo bloque de registros.
SATA define los primeros 3 de estos 16 registros:
•
Registro SStatus (Registro de Estado del interfaz SATA)
Registro de sólo lectura que el controlador actualiza constantemente para dar
información en tiempo real sobre el estado del interfaz y del controlador.
•
Registro SError (Registro de Error del interfaz SATA)
Registro de lectura/escritura que el controlador actualiza con información sobre errores
en el interfaz (un bit para cada tipo de error). El registro indica todos los errores
acumulados desde que se borró por última vez. El software puede escribir en el registro
para borrar los bits activados.
•
Registro SControl (Registro de Control del interfaz SATA)
Registro de lectura/escritura por medio del cual el software puede controlar funciones
del interfaz SATA. Las escrituras producen que el controlador o el interfaz SATA
ejecuten alguna acción y las lecturas devuelven el último valor escrito.
47
6.3.5 Direccionamiento 48-bit
El direccionamiento 48-bit es una opción que permite trabajar con discos de hasta
281,474,976,710,655 sectores. Estamos hablando de discos de más de 144 peta bytes de
memoria (144,115,188,075,855,360 bytes). Además el número de sectores que se puede
transferir con un solo comando se incrementa con la ampliación del registro contador de
sectores a 16 bits.
Los comandos válidos para este direccionamiento son:
•
•
•
•
•
•
•
•
•
•
•
•
FLUSH CACHE EXT
READ DMA EXT
READ DMA QUEUED EXT
READ MULTIPLE EXT
READ NATIVE MAX ADDRESS EXT
READ SECTOR(S) EXT
READ VERIFY SECTOR(S)
SET MAX ADDRESS EXT
WRITE DMA EXT
WRITE DMA QUEUED EXT
WRITE MULTIPLE EXT
WRITE SECTOR(S) EXT
El direccionamiento 48-bit solo funciona con LBA (logical block address: dirección
lineal del sector). Los dispositivos que implementan este tipo de direccionamiento son
compatibles con el direccionamiento 28-bit anteriormente implementado. Toda la
información sobre las compatibilidades se puede encontrar en la respuesta al comando
Identify (anexo 2).
En los dispositivos que implementan el direccionamiento 48-bit, el registro de
características, el registro contador de sectores, los LBA bajo, medio y alto son de 16
bits del tipo FIFO. Cuando uno de estos registros se escribe, el contenido escrito se pone
en la parte: “recientemente escrita”, y el contenido escrito anteriormente se pone en la
parte: “anteriormente escrita”. Por ejemplo, cuando enviamos el comando Read Sector
EXT a un dispositivo que implementa el direccionamiento 48 bit, las direcciones usadas
son las descritas en la siguiente tabla.
Registro
“recientemente escrito”
“anteriormente escrito”
Características
Contador de sectores
Reservado
Número de sectores (7:0)
Reservado
Número de sectores (15:8)
LBA bajo
LBA (7:0)
LBA (31:24)
LBA medio
LBA (15:8)
LBA (39:32)
LBA alto
LBA (23:16)
LBA (47:40)
Dispositivo
Los bits 7 y 5 no importan. El
bit LBA tiene que estar a 1.
El bit DEV tiene que indicar el
dispositivo. Los bits (3:0)
están reservados.
Reservado
48
Cuando se escribe el comando Read Sector se utiliza el direccionamiento 28-bit.
Entonces el resultado es el descrito en la siguiente tabla. La descripción de estos
registros es la misma que la descripción de los comandos.
Registro
“recientemente escrito”
“anteriormente escrito”
Características
Nada
Nada
Contador de sectores
Número de sectores (7:0)
Nada
LBA bajo
LBA (7:0)
Nada
LBA medio
LBA (15:8)
Nada
LBA alto
LBA (23:16)
Nada
Dispositivo
LBA (27:24)
Nada
El controlador debe leer el contenido “anteriormente escrito” del registro de
características, el registro contador de sectores y los LBA alto, bajo y medio cuando el
bit HOB del registro de control del dispositivo esta a 1, y después leer el contenido
“recientemente escrito” de todos los registros. Si el bit HOB (bit 7) del registro
controlador del dispositivo está a cero, el controlador lee el contenido “recientemente
escrito” de los registros. La escritura a cualquier registro del bloque de comando causa
la puesta a cero del bit HOB.
El dispositivo indica la compatibilidad con el direccionamiento 48-bit en la respuesta al
comando Identify. Además las palabras (103:100) contienen el número máximo más 1
de los LBA del dispositivo que son accesibles por los comandos del direccionamiento
48-bit.
49
6.3.6 Descripción de comandos
Los comandos permiten al Host informar al dispositivo de las acciones que se pretenden
hacer. Se trata de una serie de códigos que hacen referencia a cada acción. Los
comandos se sirven escribiendo primero, en los registros correspondientes, los
parámetros necesarios para la ejecución del mismo y después escribiendo el código del
comando en el registro de comandos. Los registros que se deben escribir dependen del
comando, por esta razón vamos a indicarlos con un contenido especifico en el apartado
Entradas de cada comando.
La descripción de cada comando tendrá unos sub-apartados:
• Descripción: descripción de la función del comando.
• Código del comando: especifica el código para este comando.
• Protocolo: especifica el protocolo usado por el comando.
• Entradas: describe los datos de los diferentes registros que subministrará el Host
• Respuesta normal: describe los datos devueltos del disco cuando se finaliza la
ejecución del comando.
• Respuesta a error: describe los datos devueltos por el disco cuando se produce
un error.
• Prerrequisitos: describe las condiciones iníciales necesarias.
A continuación vamos a ver la descripción de algunos comandos que se han utilizado en
la realización del código del programa de gestión del disco duro.
6.3.5.1 Read Sectors
Descripción:
Este comando lee entre 1 y 256 sectores depende del número que se carga en el registro
de cuenta de sectores. Si cargamos un 0 en este registro se transfieren 256 sectores. La
transferencia empieza a partir del sector especificado en los registros LBA alto, medio y
bajo y el registro del dispositivo.
El bit DRQ está siempre a 1 antes de una trasferencia de datos independientemente de la
presencia de una condición de error. El disco debe interrumpir por cada transferencia de
bloque DRQ.
Código del comando: 20h
Protocolo: PIO Data-in
Entradas:
50
• Sector count (registro de cuenta de sectores): el número de sectores que se
pretenden transferir.
• LBA Low (LBA bajo): la parte más baja del número de sector (7:0) se carga en
este registro.
• LBA Mid (LBA medio): en este registro se cargan los bits (15:8) del numero del
sector.
• LBA High (LBA alto): los bits (23:16) del LBA.
• Device (registro del dispositivo): El bit DEV selecciona el dispositivo 0 o 1 y los
bits (3:0) es donde se escriben los bits (27:24) del LBA
Respuesta normal:
• Registro del dispositivo (device): DEV indica el dispositivo seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando la finalización del comando
- DRDY se pone a 1.
- DF se pone a 0.
- DRQ y ERR se ponen a 0.
Respuesta a error:
Cualquier error encontrado durante la ejecución del comando causa la finalización de
todo el procedimiento. El bloque de registros de comando tiene la dirección del primer
sector donde ocurrió el error.
• Registro de error:
- UNC se pone a 1 cuando los datos no son correctos.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
51
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
Prerrequisitos: DRDY tiene que estar a 1
52
6.3.5.2 Read Sectors EXT
Descripción:
Este comando lee entre 1 y 65,536 sectores depende del número que se carga en el
registro de cuenta de sectores. Si cargamos un 0 en este registro se transfieren 65,536
sectores. La transferencia empieza a partir del sector especificado en los registros LBA
alto, medio y bajo y el registro del dispositivo.
El bit DRQ está siempre a 1 antes de una trasferencia de datos independientemente de la
presencia de una condición de error. El disco debe interrumpir por cada transferencia de
bloque DRQ.
Todos los comandos EXT sirven para direccionamiento 48-bit y no son compatibles con
el modo 28-bit.
Código del comando: 24h
Protocolo: PIO data-in
Entradas:
* La explicación de procedimiento a seguir para escribir estos registros esta en el
apartado direccionamiento 48-bit.
• En el registro del dispositivo: el bit LBA se tiene que poner a 1 para indicar que
la dirección especificada es un LBA. El bit DEV indica el dispositivo
seleccionado.
Respuesta normal:
La respuesta normal es idéntica a la respuesta normal del comando Read sector.
53
Respuesta a error:
La respuesta a error es idéntica a la respuesta a error del comando Read sector.
Prerrequisitos:
DRDY tiene que estar a 1.
54
6.3.5.3 Write Sectors
Descripción:
Este comando escribe entre 1 y 256 sectores depende del número que se carga en el
registro de cuenta de sectores. Si cargamos un 0 en este registro escribimos 256
sectores. El disco debe interrumpir por cada transferencia de bloque DRQ.
Código del comando: 30h
Protocolo: PIO data-out
Entradas:
Los registros LBA bajo, medio y alto y el registro del dispositivo especifican la
dirección del primer sector que va a ser escrito. En el registro de cuenta de sectores se
debe especificar el número de sectores que se pretenden escribir.
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
55
Respuesta a error:
Cualquier error encontrado durante la ejecución del comando causa la finalización de
todo el procedimiento. El bloque de registros de comando tiene la dirección del primer
sector donde ocurrió el error.
• Registro de error:
- WP se pone a 1 cuando el dispositivo está protegido contra escritura.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
Prerrequisitos:
DRDY tiene que estar a 1.
56
6.3.5.4 Write Sectors EXT
Descripción:
Este comando escribe entre 1 y 65,536 sectores depende del número que se carga en el
registro de cuenta de sectores. Si cargamos un 0 en este registro escribimos 65,536
sectores. El disco debe interrumpir por cada transferencia de bloque DRQ.
Este comando es para direccionamiento 48-bit. (Véase el apartado direcc. 48-bit)
Código del comando: 34h
Protocolo: PIO data-out
Entradas:
Los registros LBA alto, medio y bajo deben ser escritos con la dirección del primer
sector donde se empezará a escribir. (La forma de escribir estos sectores está explicada
en el apartado direccionamiento 48-bit).
El bit DEV especifica el dispositivo que se pretende escribir.
57
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
Respuesta a error:
Cualquier error encontrado durante la ejecución del comando causa la finalización de
todo el procedimiento. El bloque de registros de comando tiene la dirección del primer
sector donde ocurrió el error.
Los bits de la respuesta a error son idénticos a los bits de la respuesta a error del
comando Write sector. Lo único que cambia es la dirección del LBA que está codificada
con 48 bits.
Prerrequisitos:
DRDY tiene que estar a 1.
58
6.3.5.5 Read multiple
Descripción:
Este comando lee el número de sectores especificado en el registro de cuenta de
sectores. El número de sectores por bloque esta especificado en la palabra 59 de la
respuesta al comando Identify Device.
Cuando se manda el comando Read multiple, el registro de cuenta del dispositivo debe
contener el número de sectores (no de bloques) solicitados. El dispositivo debe
interrumpir por cada bloque enviado.
Si el número de sectores no es divisible por el número de bloques, se mandan antes los
bloques completos y después, al final, se manda el bloque parcial.
Si se intenta mandar este comando mientras está desactivada está opción, la respuesta
será abortar el comando.
Cuando se encuentra un error se publica la dirección del principio del bloque completo
o parcial. Pero el bit DRQ se mantiene a 1 y la transferencia de datos se hace
igualmente. El controlador debe reintentar la transferencia a partir de esa dirección.
El comando se continúa ejecutando solo cuando hay un error en los datos. Los demás
errores causan la interrupción de la operación por completo.
Código del comando: C4h
Protocolo: PIO data-in
Entradas:
• Sector Count: especifica el número de sectores que se quieren transferir.
• LBA alto, medio, bajo y registro del dispositivo especifican el primer sector
donde se empieza la transferencia.
• DEV selecciona el dispositivo sobre el cual se realizará la operación.
Prerrequisitos:
DRDY tiene que estar a 1.
59
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
Respuesta a error:
• Registro de error:
- UNC se pone a 1 cuando los datos no son correctos.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
60
6.3.5.6 Read multiple EXT
Descripción:
Este comando tiene la misma función que el comando Read Multiple. La diferencia
entre los dos se basa en que este comando es para direccionamiento 48-bit y el segundo
es para 28 bits.
Este comando permite transferir hasta 65,536 sectores en lugar de 256.
Código del comando: 29h
Protocolo: PIO data-in
Entradas:
Respuesta normal:
La respuesta normal es idéntica a la del comando Read multiple.
Respuesta a error:
La respuesta a error es idéntica a la del comando Read multiple.
Prerrequisitos:
Los prerrequisitos son los mismos.
61
6.3.5.7 Write multiple
Descripción:
Este comando escribe el número de sectores especificado en el registro de cuenta de
sectores. El número de sectores por bloque esta especificado en la palabra 59 de la
respuesta al comando Identify Device.
Cuando se manda el comando Write multiple, el registro de cuenta del dispositivo debe
contener el número de sectores (no de bloques) solicitados. El dispositivo debe
interrumpir por cada bloque enviado.
Si el número de sectores no es divisible por el número de bloques, se mandan antes los
bloques completos y después, al final, se manda el bloque parcial.
Si se intenta mandar este comando mientras está desactivada está opción, la respuesta
será abortar el comando.
Cuando se encuentra un error se publica la dirección del principio del bloque completo
o parcial. La operación se interrumpe aunque el dispositivo este escribiendo un sector
que está en el medio del bloque. A partir de allí no se envía ningún bloque.
Código del comando: C5h
Protocolo: PIO data-out
Entradas:
Los registros LBA alto, medio y bajo y el registro del dispositivo especifican el primer
sector que se tiene que escribir. El registro contador de sectores especifica el numero de
sectores que se deben escribir.
Si en el registro contador se escribe un cero, el número de sectores que se van a
transferir es 256.
El bit DEV selecciona el dispositivo sobre el cual se desea trabajar.
62
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
Respuesta a error:
• Registro de error:
- WP se pone a 1 cuando el dispositivo está protegido contra escritura.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
63
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
Prerrequisitos:
DRDY tiene que estar a 1.
64
6.3.5.8 Write multiple EXT
Descripción:
Este comando tiene la misma función que el comando Write Multiple. La diferencia
entre los dos se basa en que este comando es para direccionamiento 48-bit y el segundo
es para 28 bits.
Este comando permite transferir hasta 65,536 sectores en lugar de 256.
Código del comando: 39h
Protocolo: PIO data-out
Entradas:
Respuesta normal:
La respuesta normal es idéntica a la del comando Write multiple.
Respuesta a error:
La respuesta a error es idéntica a la del comando Write multiple.
Prerrequisitos:
Los prerrequisitos son los mismos.
65
6.3.5.9 Read DMA
Descripción:
El comando Read DMA permite al Host leer datos usando el protocolo DMA en la
transferencia de datos.
Código del comando: C8h
Protocolo: DMA
Entradas:
• Sector Count especifica el número de sectores que se pretenden transferir.
• El bit DEV selecciona el dispositivo.
• LBA alto, medio y bajo y el registro del dispositivo contienen la dirección del
primer sector.
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
66
Respuesta a error:
Cualquier error encontrado durante la ejecución del comando causa la finalización de
todo el procedimiento. El bloque de registros de comando tiene la dirección del primer
sector donde ocurrió el error.
• Registro de error:
- ICRC se tiene que poner a 1 cuando ocurre un error en la interfaz durante la
transferencia de datos vía Ultra DMA
- UNC se pone a 1 cuando los datos no son correctos.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
Prerrequisitos:
DRDY tiene que estar a 1 y el controlador debe inicializar el canal DMA.
67
6.3.5.10 Read DMA EXT
Descripción:
El comando Read DMA EXT permite al Host leer datos usando el protocolo DMA en la
transferencia de datos.
Este comando es para direccionamiento 48-bit.
Código del comando: 25h
Protocolo: DMA
Entradas:
Respuesta normal:
La respuesta normal es idéntica a la del comando Read DMA.
Respuesta a error:
La respuesta a error es idéntica a la del comando Read DMA.
Prerrequisitos:
Los prerrequisitos son los mismos.
68
6.3.5.11 Write DMA
Descripción:
El comando Read DMA EXT permite al Host escribir datos usando el protocolo DMA
en la transferencia de datos.
Código del comando: CAh
Protocolo: DMA
Entradas:
Los registros LBA alto, medio y bajo y el registro del dispositivo especifican el primer
sector que se tiene que escribir. El registro contador de sectores especifica el numero de
sectores que se deben escribir.
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
69
Respuesta a error:
• Registro de error:
- ICRC se tiene que poner a 1 cuando ocurre un error en la interfaz durante la
transferencia de datos vía Ultra DMA.
- WP se pone a 1 cuando el dispositivo está protegido contra escritura.
- MC se pone a 1 si media cambió desde el último comando ejecutado. El
dispositivo debe pone este bit a cero más tarde.
- IDNF se pone a 1 cuando no se encuentra una dirección accesible por el
usuario. Este bit se pone a 1 cuando la dirección solicitada no está dentro del
rango de direcciones accesibles por el dispositivo siempre y cuando bit de
comando abortado no se ha activado.
- MCR se pone a 1 cuando hay una petición de cambio de media de un
dispositivo de media removible.
- ABRT se pone a 1 cuando el comando no es compatible o bien el dispositivo
no puede cumplir las acciones requeridas por el comando. Este bit se tiene que
poner a 1 cuando se sale del rango de direcciones permitidas siempre y cuando
IDNF no se active.
• LBA bajo, LBA medio, LBA alto y registro del dispositivo: estos registros
contienen la dirección del primer error ocurrido. El bit DEV indica el dispositivo
seleccionado.
• Registro de estado:
- BSY se pone a 0 indicando el fin de ejecución del comando.
- DRDY se pone a 1.
- DF se tiene que poner a 1 si hay un fallo del dispositivo.
- DRQ se tiene que poner a 0
- ERR se tiene que poner a 1 cuando se trata de un error indicado por los bits del
registro de error.
Prerrequisitos:
DRDY tiene que estar a 1 y el controlador debe inicializar el canal DMA.
70
6.3.5.12 Write DMA EXT
Descripción:
El comando Write DMA EXT permite al Host escribir datos usando el protocolo DMA
en la transferencia de datos.
Este comando es para direccionamiento 48-bit.
Código del comando: 35h
Protocolo: DMA
Entradas:
Respuesta normal:
La respuesta normal es idéntica a la del comando Write DMA.
Respuesta a error:
La respuesta a error es idéntica a la del comando Write DMA.
Prerrequisitos:
Los prerrequisitos son los mismos.
71
6.3.5.13 Identify Device
Descripción:
El comando Identify permite al Host recibir información del dispositivo.
Algunos dispositivos necesitan leer los datos con cierto orden para completar el
comando.
Cuando se envía este comando, el dispositivo pone a 1 el bit BSY del registro de estado
y se prepara para enviar 256 palabras de identificación del mismo al controlador, pone
el bit DRQ a 1, desactiva el BSY y interrumpe al Host. Entonces es cuando el
controlador empieza a recuperar los datos leyendo del registro de datos. El anexo 2
contiene la explicación con detalle de la información que contienen estas 256 palabras.
Algunos parámetros superan el tamaño de un Word (16 bits), entonces lo que se hace es
dividir el parámetro en varios Word ordenados.
Código del comando: ECh
Protocolo: PIO data-in
Entradas:
* En este caso lo único que se tiene que especificar es el dispositivo mediante el bit
DEV.
72
Respuesta normal:
•
•
•
•
El bit DEV indica el dispositivo seleccionado.
El bit BSY se pone a cero cuando se cumple la ejecución del comando.
El bit DRDY se pone a 1.
Los bits DF, DRQ, ERR se ponen a 0
Respuesta a error:
Los dispositivos no deben presentar en ningún error haciendo ejecutando este comando.
Prerrequisitos:
DRDY tiene que estar a 1.
73
6.3.5.14 Device reset
Descripción:
El comando Device reset permite al host resetear un solo dispositivo sin afectar a los
otros dispositivos.
Código del comando: 08h
Protocolo: Device reset.
Entradas:
* En este caso lo único que se tiene que especificar es el dispositivo mediante el bit
DEV.
Respuesta normal:
• El resultado del diagnostico se especifica en el registro de error.
• El bloque de registros de comando se carga con la firma.
• El registro de estado se pone a su estado normal:
o El bit BSY se pone a cero cuando se cumple la ejecución del comando.
o El bit DRDY se pone a 1.
o Los bits DF, DRQ, ERR se ponen a 0
Respuesta a error:
Si el dispositivo es compatible con este comando, no tiene que haber ningún error. Si
este comando no es compatible y los bits BSY o DRQ están a 1, el resultado es
indeterminado. En cambio, si no lo están el dispositivo activará el bit Comando
abortado del registro de error.
74
6.4 SATA II
A partir del desarrollo de SATA se han abierto nuevas líneas de trabajo, todas ellas
recogidas bajo el nombre genérico de SATA II. Estas líneas y sus principales
características (por ahora) son:
6.4.1 Extensiones de SATA
Define una serie de extensiones sobre la especificación original SATA, que añaden
nuevas posibilidades manteniendo la compatibilidad. Las extensiones pueden adoptarse
por separado y según convenga por razones de mercado. Las más significativas son:
• Una extensión a nivel eléctrico que permite la conexión de los controladores
SATA II a un panel de conectores de 18”, de forma que los dispositivos actuales
SATA se puedan conectar a dicho panel. Está enfocado a permitir la
construcción de Arrays de discos (JBODs y RAIDs) en un rack estándar de 19”
utilizando los servicios de cabinas de discos estándar tanto SAFTE (SCSI
Accessed Fault-Tolerant Enclosure) como SES (SCSI Enclosure Services), las
cuales se pueden conectar a un controlador SATA II (controlador normal o
controlador RAID) o a cualquier otro sistema de interconexión como pueda ser
Fibre Channel, Infiniband, Gigabit Ethernet (iSCSI), etc.
• Nuevos comandos de lectura/escritura que utilizan un nuevo modelo de encolado
nativo de comandos. El nuevo modelo de encolado está basado en el modelo
heredado ATA, aunque con algunos aspectos modificados para aprovechar las
nuevas posibilidades que ofrece SATA. Los dispositivos pueden encolar hasta
32 comandos y utilizan el mecanismo nativo First-Party DMA para ejecutar las
transferencias de datos.
• Nuevo método de notificación de eventos (Notificación Asíncrona), en la que el
dispositivo avisa directamente al controlador cuando sucede un evento que
requiera su atención (por ejemplo, la inserción de una media en un dispositivo
de medios removibles). Esta función elimina la necesidad de que el controlador
esté continuamente interrogando a los dispositivos para comprobar si ha
sucedido un evento.
6.4.2 Multiplicador de Puertos
Define un mecanismo al estilo de un multiplexor, mediante el cual el controlador SATA
II junto con nuevo software nativo puede comunicarse con diferentes dispositivos
SATA, en concreto hasta con un máximo de 15.
La arquitectura está pensada para que un sistema con software heredado (BIOS y
drivers actuales) o que disponga de un controlador SATA (o SATA II que no
implemente la gestión del Multiplicador) pueda arrancar el sistema y trabajar con un
dispositivo SATA conectado al puerto 0 del Multiplicador.
Principalmente está enfocado a la construcción de Arrays de discos (a los que sólo hay
que hacerles llegar una o dos líneas SATA, permitiendo mediante Multiplicadores
internos al Array la conectividad con hasta 15 discos por cada línea SATA de entrada) y
75
la ampliación de puertos en equipo móviles (por ejemplo, integrando el Multiplicador
en la dock-station).
Otras características del Multiplicador son el soporte de hot-plug, el arranque controlado
de los discos y la Notificación Asíncrona para avisar al controlador sobre nuevas
conexiones de dispositivos a los puertos.
El controlador SATA II puede gestionar el acceso a los dispositivos de dos formas, lo
cual es independiente del Multiplicador en sí:
• Cambio de contexto por comando: Los controladores que soportan este modo de
gestión sólo pueden enviar comandos a los dispositivos de uno en uno. Sólo un
dispositivo puede en cada momento estar ejecutando un comando.
• Cambio de contexto por trama: Los controladores que soportan este modo de
gestión pueden enviar comandos a todos los dispositivos concurrentemente.
6.4.3 Selector de Puerto
Define un mecanismo, al estilo también de un multiplexor, que permite a dos
controladores SATA (junto con nuevo software nativo) acceder a un dispositivo SATA,
creando un acceso redundante.
No está pensado como sistema multi-controlador en el que los dos controladores
acceden concurrentemente al dispositivo, sino como sistema tolerante a fallo en el que
un controlador es el activo y el otro es el de repuesto, a modo de hot-spare, que toma el
control cuando el controlador activo falla.
6.4.4 Cables y Conectores
Define distintas mejoras sobre la especificación SATA para permitir la conexión de
dispositivos SATA en entornos servidores y de red, definiendo tanto las conexiones
internas (entre la placa base o placa controladora y un panel de conectores), como las
conexiones externas (entre un servidor y un Array externo situado en la misma cabina).
76
7 El lenguaje de programación C
El lenguaje de programación C fue creado entre 1970 y 1972 por Brian Kernighan y
Dennis Ritchie para escribir el código del sistema operativo UNIX.
Desde su nacimiento se fue implantando como el lenguaje de programación de sistemas
favorito para muchos programadores, sobre todo por ser un lenguaje que conjugaba la
abstracción de los lenguajes de alto nivel con la eficiencia del lenguaje máquina. Los
programadores de sistemas que trabajaban sobre MS-DOS y Macintosh también
utilizaban C, con lo cual la práctica totalidad de aplicaciones de sistema para
microordenadores y para sistemas UNIX está escrita en este lenguaje.
A mediados de los ochenta el C se convierte en un estándar internacional ISO. Este
estándar incluye tanto la definición del lenguaje como una enorme biblioteca de
funciones para entrada / salida, tratamiento de textos, matemáticas, etc.
A mediados de los ochenta se crea el C++, extensión de C orientada a objetos. El C++
se convierte en estándar ISO en 1998. En el momento actual, el lenguaje C no va a
modificarse más. Será el C++ el que incorporará nuevos cambios.
El lenguaje C es el resultado de un proceso de desarrollo que inició con un lenguaje
denominado BCPL. Este influenció a otro llamado B (inventado por Ken Thompson).
En los años 70; éste lenguaje llevó a la aparición del C.
Con la popularidad de las microcomputadoras muchas compañías comenzaron a
implementar su propio C por lo cual surgieron discrepancias entre sí.
Por esta razón ANSI (American National Standars Institute, por sus siglas en inglés),
estableció un comité en 1983 para crear una definición no ambigua del lenguaje C e
independiente de la máquina que pudiera utilizarse en todos los tipos de C.
Algunos de las C existentes son: Quick C, C++, Turbo C, Turbo C ++, Borland C,
Borland C++, Microsoft C, etc.
C es un lenguaje de programación de nivel medio ya que combina los elementos del
lenguaje de alto nivel con la funcionalidad del ensamblador.
Su característica principal es ser portable, es decir, es posible adaptar los programas
escritos para un tipo de computadora en otra.
Otra de sus características principales es el ser estructurado, es decir, el programa se
divide en módulos (funciones) independientes entre sí.
El lenguaje C inicialmente fue creado para la programación de: Sistemas operativos,
Intérpretes, Editores, Ensambladores, Compiladores, Administradores de bases de datos.
Actualmente, debido a sus características, puede ser utilizado para todo tipo de
programas.
77
El C es un lenguaje de programación de propósito general, Sus principales
Características son:
•
•
•
•
•
•
•
•
•
Programación Estructurada
Economía en las expresiones
Abundancia en operadores y tipos de datos
Codificación de Alto y Bajo nivel simultáneamente
Reemplaza ventajosamente la programación en ensamblador
Utilización natural de las funciones primitivas del sistema
No está orientado a ningún área en especial
Producción de código objeto altamente optimizado
Facilidad de aprendizaje
Los tipos básicos de datos eran "CHAR" (carácter), "INT" (enteros), "FLOAT" (Reales
en simple precisión), y "DOUBLE" (Reales en doble Precisión). Posteriormente se
añadieron los tipos "SHORT" (Enteros de longitud<=longitud de un int), "LONG"
(Enteros de longitud >= longitud de un entero), "UNSIGNED" (Enteros sin signo), y
"ENUMERACIONES". Los tipos estructurados básicos de C son las estructuras, las
uniones, y los arrays. Estos permiten la definición y declaración de tipos de mayor
complejidad.
Las instrucciones de control de flujo de C son las habituales de la programación
estructurada: IF, FOR, WHILE, SWITCH - CASE, todas incluidas en su predecesor
BCPL.
C incluye también punteros y funciones. Los argumentos de las funciones se pasan por
valor, esto es copiando su valor, lo cual hace que no se modifiquen los valores de los
argumentos en la llamada. Cuando se desea modificar los argumentos en la llamada,
éstos se pasan por referencia, es decir, se pasan las direcciones de los argumentos. Por
otra parte, cualquier función puede ser llamada recursivamente.
Una de las peculiaridades de C es su riqueza de operadores. Puede decirse que
prácticamente dispone de un operador para cada una de las posibles operaciones en
código máquina.
Hay toda una serie de operaciones que pueden hacerse con el lenguaje C, que realmente
no están incluidas en el compilador propiamente dicho, sino que las realiza un
preprocesador justo antes de cada compilación. Las dos más importantes son #define
(directriz de sustitución simbólica o de definición) e #include (Directriz de inclusión en
el fichero fuente)
Finalmente, C, que ha sido pensado para ser altamente transportable y para programar lo
improgramable, igual que otros lenguajes tiene sus inconvenientes. Carece de
instrucciones de entrada/salida, de instrucciones para manejo de cadenas de caracteres,
con lo que este trabajo queda para la librería de rutinas, con la consiguiente pérdida de
transportabilidad. La excesiva libertad en la escritura de los programas puede llevar a
errores en la programación que, por ser correctos sintácticamente no se detectan a
simple vista. Por otra parte las precedencias de los operadores convierten a veces las
expresiones en pequeños rompecabezas. A pesar de todo, C ha demostrado ser un
lenguaje extremadamente eficaz y expresivo.
78
8 Desarrollo del software
Una vez vista la información sobre el hardware que vamos a necesitar para el desarrollo
del proyecto, empezamos con el análisis del software. Como ya se ha comentado en la
introducción, para la realización de este proyecto partimos de un software heredero que
vamos a modificar para conseguir cumplir las especificaciones inicialmente
concretadas.
El programa heredero, creado por el profesor Esteban Del Castillo, dispone de 12
archivos del tipo *.C y 12 archivos de cabecera. En este caso podemos distinguir entre
los ficheros que controlan la parte gráfica y los de la parte funcional, aunque a veces, a
nivel de enlace entre las dos partes, hay algunos ficheros que contienen variables
compartidas.
Es importante decir que la modificación de la parte funcional impone una modificación
parcial de la gráfica. Pues con la actualización del software se necesitarán más
variables, más espacio para visualizarlas y también nuevas técnicas de conversión del
contenido introducido por el usuario.
Figura 10. Diagrama de flujo simplificado. En azul el inicio, en verde las opciones que se pueden seleccionar y
en rojo partes que se ejecutan automáticamente.
79
8.1 Parte gráfica:
Se trata de una interfaz de usuario ya implementada junto con el software heredero. Está
compuesta básicamente por siete archivos del tipo *.C mas los correspondientes
archivos de cabecera. Hay un archivo para cada función: editar, copiar, buscar,
comparar y configurar y dos archivos para los menús que aparecen por pantalla.
El funcionamiento básico de una función cualquiera de las cinco mencionadas
anteriormente es visualizar las ventanas correspondientes a la opción seleccionada y en
el mismo tiempo ejecutar las rutinas necesarias para completar dicha función. El lazo
entre la parte funcional y la parte grafica viene después de saber el deseo del cliente
(mediante la lectura de la tecla), que es realmente cuando se ejecutan las funciones de
acceso al disco duro. Una vez obtenidos los datos del disco, cada opción los trata de
forma distinta.
Esta parte del código es totalmente válida puesto que está diseñada de forma
prácticamente independiente de la parte funcional. Lo que nos interesa ahora es ampliar
los límites establecidos para el acceso a los discos IDE. Estos límites básicamente son
los espacios reservados para la visualización en la pantalla y también las variables que
introduce el usuario.
La modificación de los espacios en pantalla es más simple que la de las variables. Pues
solo hay que localizar donde se escribe por pantalla y después modificar los parámetros.
Esta interfaz está diseñada de forma muy inteligente puesto que hay una única función
que dibuja las ventanas. Se trata de modificar las variables de tamaño de las ventanas en
las rutinas de las diferentes opciones.
Figura 11. Uno de los cambio del aspecto de la interfaz
La modificación de las variables es más compleja, pues todas las conversiones de
ASCII a binario se hacen para que el resultado sea una variable del tipo long (32 bits). A
causa del gran aumento de la memoria de los discos, ciertas variables, como por
80
ejemplo el número del sector, son insuficientes para guardar los valores. Por esta razón
se emplearán nuevas técnicas de conversión para guardar en 2 variables del tipo long en
lugar de una.
Disponíamos de una función que hace esta conversión pero que el resultado era una sola
variable. La nueva función se planteo con una idea prácticamente diferente. Pues la
primera obtiene el número tecleado por el usuario, lo guarda en un string4, después
utiliza la base 10 para calcular la cifra exacta.
Ejemplo: si el usuario teclea un 9, un 1 y un 8 para obtener el número 918 se hace lo
siguiente:
El string queda así:
9
1
8
Entonces lo que se hace es: 8*1 + 1*10 + 9*100
= 918
Equivale a:
8*10^0 + 8*10^1 + 8*10^2
= 918
El numero 918 se guarda en una variable del tipo long.
¿La pregunta ahora es: que pasa si el usuario teclea un número mayor que
4.294.967.295 (máximo valor que una variable del tipo long permite guardar)?
La respuesta es que no se guardará el valor correcto y se limitará como máximo al valor
anteriormente dicho.
La idea de la nueva rutina es obtener el número correcto y guardarlo en tantas variables
como sea necesario. Primero se hace la conversión del número tecleado a binario con la
manera tradicional: resto de divisiones entre 2 y se guarda en otro string. De esta forma
el string que contiene el resultado solo tendrá o un 1 o un 0 en cada casilla. El segundo
paso es volver a convertir el número binario a decimal mediante potencias de 2, pero
esta vez solo cogeremos los bits que suporta un long (32 bits). Entonces si por ejemplo
tenemos 48 bits ocupados: hacemos la conversión de 32 bits y los guardamos en una
variable y después hacemos la conversión de 16 bits y lo guardamos en otro variable. Es
obvio que la segunda variable contiene la parte alta del número y la primera contiene la
parte baja.
Ejemplo: si el usuario teclea el valor 1.099.511.627.771 (posición de un sector). Se
puede ver claramente que supera el límite de las variables long.
Tenemos:
1
0
9
9
5
1
1
6
2
7
7
7
1
La conversión a binario: el string que guarda el resultado quedará así:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
4
Cadena de caracteres: es una secuencia ordenada de longitud arbitraria (aunque finita) de elementos que
pertenecen a un cierto alfabeto. Desde el punto de vista de la programación, una cadena podrá estar
formada por cualquier combinación finita de todo el juego caracteres disponibles.
81
Entonces en la primera variable vamos a guardar la conversión a decimal de los 32 bits
(en naranja) y en la segunda variable guardamos la conversión a decimal de los 8 bits
restantes (en azul).
El resultado final será:
Variable1: 0xFFFFFFFB y Variable2: 0x000000FF
82
8.2 Parte funcional:
Como ya se ha comentado anteriormente, disponemos de un programa para acceso a
discos IDE de menos de 137 Gigabytes de memoria. La idea principal es modificar
este programa para conseguir el acceso a discos SATA sin limitación de memoria.
La explicación del funcionamiento de esta parte se hará de forma muy simplificada
puesto que es un programa muy complejo.
La parte funcional del programa heredero está compuesta por 4 ficheros de tipo *.C
y un fichero *.asm (ensamblador) más los correspondientes ficheros de cabecera. En
este programa vamos a trabajar sobre los tres ficheros esenciales:
• Inicialización: disk_ini.c
• Acceso al disco: ide_drv1.c
• Atención a las interrupciones: ide_drv0.asm
En el primer fichero se hace, entre otras cosas, la identificación de todos los
dispositivos que están conectados a la CPU. Estas rutinas se encargan de decidir si
el acceso será normal (disco duro) o bien por la BIOS en caso de disquetera. En el
primer caso se manda un comando de identificación a los discos. El tratamiento de
la información se hace en rutinas del segundo y tercer fichero.
Una de las funciones más importantes de las rutinas de inicialización es la
determinación del modo de operación más eficiente para los discos duros. Esta
opción se encarga de decidir el modo de acceso al disco (sea lectura o escritura). Las
opciones son: lectura o escritura de un solo sector, de varios sectores (con el
protocolo PIO) o bien, si el disco lo permite, el uso del modo Ultra DMA. La
decisión del modo más eficiente se hace asociando un comando determinado, de los
que hacen que el disco opere con los modos anteriores, a las dos opciones: lectura y
escritura
Para el acceso a discos que implementan el direccionamiento 48-bit, los comandos
son diferentes. Para cada opción vamos a tener que emplear unos condicionales
extras para saber si el disco es de direccionamiento 48-bit o bien de 28-bit. La
variable que contiene la información sobre el tipo de direccionamiento que suporta
el disco se inicializa mediante el comando Identify device.
Una vez ya conocidos los comandos que el Host debe enviar al dispositivo, empieza
el funcionamiento normal. El segundo fichero contiene rutinas para acceso al disco.
Estas rutinas se encargan de proporcionar la información necesaria al disco para
ejecutar los comandos mediante la programación de los registros.
En el caso del comando Identify Device enviado desde las rutinas de inicialización,
las rutinas de acceso al disco (disk_access( ) y x_disco( )), aparte de programar los
registros con la información necesaria, se encargan de identificar la información que
devuelve el dispositivo. La información que nos interesa es el número de serie del
dispositivo, la revisión del firmware, el modelo del disco, la compatibilidad con
transferencia de bloque, los modos PIO, los modos Ultra DMA, el número de
sectores del disco, la compatibilidad con el modo Multiword DMA.
83
Toda esta información es totalmente útil para los discos SATA. Pero aparte de ésta,
vamos a necesitar una variable que indicará si el dispositivo es compatible con el
direccionamiento 48-bit y también vamos a necesitar dos variables del tipo long
para guardar en número máximo de sectores a los que se puede acceder.
El comando Identify device sirve para todos los tipos de discos. Por lo tanto, se
puede ejecutar antes de saber el tipo de direccionamiento del disco. Es evidente que
si no fuera así, nunca sabríamos de qué tipo es el disco puesto que el mismo
comando es el encargado de devolver esta información.
Para conservar el correcto funcionamiento del programa original, vamos a crear
rutinas independientes de las originales. Eso supone crear otro “camino” en el flujo
de programa.
La variable que decide el recorrido del programa será la misma que contiene la
información de compatibilidad con el direccionamiento 48-bit.
Figura 12. Diagrama de flujo simplificado de la parte funcional.
Una vez planteada la idea, vamos a crear unas rutinas compatibles con el programa
original. En este sentido, todas las funciones tienen que ser fácilmente acopladas, es
decir, tienen que tener las mismas entradas y las mismas salidas que las rutinas del
programa heredero.
84
El acceso a los discos SATA con direccionamiento 48 bit está explicado en el
apartado 6.3.5. El código fuente de las nuevas rutinas está en el Anexo 3,
exactamente en el fichero IDE_DRV1.C. Este fichero contiene principalmente
cuatro rutinas: dos para el acceso con direccionamiento 48-bit y dos para 28-bit. Las
dos primeras rutinas y las dos segundas hacen prácticamente la misma función pero
de forma distinta.
Las rutinas disk_access28( ) y disk_access48( ) se encargan, entre varias cosas, de
hacer inicializaciones especificas para cada comando preparando el acceso DMA o
obteniendo el número de sectores para el acceso múltiple etc. En el caso del primer
acceso al disco (identificación), estas rutinas se encargan de ordenar en variables
distintas la información que devuelve el dispositivo.
Las dos rutinas anteriormente mencionadas se encargan también de llamar a las
funciones x_disco28( ) y x_disco48( ) respectivamente. La función principal de éstas
es la programación de los registros con los diferentes valores que se necesitan para
ejecutar un comando determinado y después esperar la respuesta del dispositivo.
Aparte de esto, estas rutinas se encargan también de gestionar la respuesta a error
del dispositivo, permitiendo al usuario darse cuenta mediante los distintos mensajes
de error.
El tercer fichero modificado es IDE_DRV0.asm. El fichero de código Assembler
contiene rutinas de atención a las dos interrupciones que genera el disco duro (para
los dos canales). La función de estas dos rutinas es idéntica, pues las dos se
encargan del tratamiento de datos ya sea para una lectura (obteniendo datos del
disco y guardándolos en memoria) o bien para una escritura (escritura desde la
memoria al dispositivo). Éstas también se encargan de modificar el estado del flanco
utilizado para saber si el dispositivo ha acabado o bien está ejecutando el comando.
El fichero IDE_DRV0.asm también contiene funciones para el bus PCI. Son
funciones para el acceso limitado al disco y a las disqueteras mediante el uso de la
BIOS del sistema.
El código fuente de todo el programa está comentado en el anexo 3.
85
8.3 Pasos para la realización del software
Después de la explicación del funcionamiento del software me gustaría repasar un
poco las etapas de realización de este proyecto. Pues me he encontrado con todo tipo
de problemas pero gracias a la gran ayuda de mi tutor, los he podido superar. En este
apartado del proyecto hablaré un poco de los problemas que han surgido.
Lo primero que hice fue buscar información sobre los discos SATA. Creo que fue
una de las etapas más difíciles del proyecto. La información que se podía encontrar
en la web era sobre las características de estos discos y nunca sobre cómo acceder a
éstos. Nunca me había imaginado que el mismo estándar de los discos IDE hablaba
de los discos SATA en su octava edición.
Una vez entendido aproximadamente como se puede acceder al disco, y para
habituarme más al funcionamiento de éstos, mi tutor el profesor Esteban Del
Castillo, me pidió hacer un programa que acceda a los dos tipos de discos, IDE y
SATA. La interfaz no tenía importancia porque es un programa para practicar y
aprender. Después de un tiempo trabajando sobre este programa conseguí acabarlo,
y con esto tuve luz verde para comenzar la modificación del programa heredero.
Figura 13. Captura de pantalla mientras se ejecuta el primer programa de acceso al disco.
El programa heredero está compuesto por nada más y nada menos un total de 24
ficheros de código. Por suerte la mitad de estos pertenecían a la parte gráfica y no
los tenía que modificar al principio. Estamos hablando de un programa súper
complejo que se ha realizado en varios años. Entender el código de cada rutina,
como estaba relacionada con las otras, cuando se le llama y que es lo que realmente
hacía me llevo prácticamente la mitad del tiempo dedicado a esto proyecto.
Obviamente, es más difícil entender el código de un programa ya hecho que hacerlo.
La primera modificación que he realizado del proyecto no acaba de agradar, ya que
había modificado las mismas rutinas añadiendo código para el acceso a los discos
SATA y además no funcionaba como tenía que hacerlo. De allí salió la idea de hacer
que el programa funcione solamente con SATA y más tarde conseguir los dos
86
funcionamientos a la vez. Eso supone la eliminación de las rutinas de acceso a
discos IDE y crear otras funciones nuevas.
Tardé dos meses en conseguir que el programa funcione con SATA, con este
resultado pensé que prácticamente el programa está listo. Pues solo falta añadir las
rutinas viejas y hacer que el programa sea compatible mediante unos cuantos
condicionales. A causa de un problema inesperado con el compilador que utilizaba
perdí mucho tiempo, ya que las modificaciones que hacía del código no daban
ningún resultado positivo. Era el momento oportuno para solicitar ayuda de mi tutor
el profesor Esteban. Él me dejó trabajar en su laboratorio utilizando su propio
ordenador.
La primera versión del programa que se ha realizado es para acceso a discos SATA
de menos de 2,2 terabytes de memoria porque era el valor máximo que soportaban
las variables del tipo long. La siguiente fase consistía en hacer que el programa
acceso a todos los discos independientemente de su capacidad de almacenamiento.
Para ello se modificaron varias variables y se introdujeron otras nuevas. Es obvio
que introducir nuevas variables cause nuevas modificaciones de código, ya sea
generando nuevas líneas o bien cambiando el mismo texto hecho anteriormente.
Con cada modificación de la parte funcional, los cambios de la parte gráfica se
requerían más. Era el momento de adaptar la interfaz al programa. Modificar las
variables que usa ésta y la manera de obtener los valores es la parte esencial de la
modificación, aparte claramente de la modificación de la apariencia y los espacios.
Una vez hechas las modificaciones principales, me he dado cuenta que hay ciertas
cosas que se tienen que cambiar para acabar de perfeccionar el programa. La idea es
eliminar las líneas de código no necesarias, minimizar el número de variables
utilizadas, tratar casos especiales de discos (algunos discos no llegan a 137GB de
memoria pero implementan el direccionamiento 48-bit), etc.
87
9 Resultados finales
El resultado final de todo el código explicado anteriormente presenta la siguiente
forma visual de inicio:
Figura 14. Pantalla principal del programa.
Después de la presentación del programa y el mensaje de advertencia, podemos ver
todos los discos que están conectados. En este caso solo se puede ver la disquetera
porque el programa se ha ejecutado en Windows para hacer la captura de pantalla.
Cuando se inicia el programa en MS-DOS se pueden ver los discos duros,
disqueteras y también las unidades de memoria USB. Podemos ver en el centro de la
pantalla las cinco opciones que el usuario puede seleccionar más la opción de salida.
A continuación vamos a ver con detalle las diferentes opciones que ofrece este
programa al usuario. Para hacer más entendible la explicación, ésta irá acompañada
de una captura de pantalla hecha en Windows donde solamente se puede acceder a
la disquetera.
9.1 La función Editar
La opción de edición es la primera del menú. Ésta nos permite ver de forma
explícita la información que tiene el disco. Esta información está en binario y en
código ASCII.
88
Figura 15. Edición del disco
En la parte superior de la pantalla podemos ver la información del disco como ahora
el número de la unidad, el modelo (normalmente disquetera o disco duro), el número
del sector y el cilindro-cabeza-sector (el primer sistema de direccionamiento para
discos duros antes de que se crea el direccionamiento por el número del sector
LBA).
En la parte inferior podemos ver una pequeña guía para el usuario. Los comandos
permitidos son F3 para editar cualquier bit de la tabla, F5 para guardar estos
cambios, ESC para ver el menú, la flechas sirven para avanzar los sectores y los
cilindros y para avanzar la cabezas usamos las teclas de avance de página. Las teclas
inicio y fin también están habilitadas.
Todo el resto de la pantalla se conserva para la visualización de la información. En
cada pantalla solo se puede visualizar medio sector. En la parte izquierda podemos
ver el offset de cada Word del sector. En la parte media están los datos en
hexadecimal. Y en la parte derecha podemos ver los mismos datos pero en código
ASCII.
Si pulsamos la tecla ESC salta el menú de esta opción. Éste nos permite cambiar de
unidad, ir al sector o al cilindro-cabeza-sector que deseamos o bien salir.
9.2 La opción Copiar
Esta opción se creó para facilitar al usuario la transferencia de datos entre dos discos
en un tiempo reducido.
89
Figura 16. Copiando datos del disco
Esta opción nos permite seleccionar la unidad de origen donde se encuentran los
datos que se tienen que copiar, la unidad de destino, el primer sector de donde
empieza la transferencia, el primer sector del disco receptor, el numero de sectores
(se puede seleccionar todo el disco o bien una cantidad en sectores o megabytes) y
finalmente el archivo donde se guarda la información del procedimiento.
Esta opción es muy útil para hacer copiar de seguridad con la totalidad de la
información que contiene el disco, incluido el sistema operativo. Pues el nuevo
disco solo necesitara ser instalado para hacer la misma función que el original.
9.3 La opción Comparar
Esta opción nos permite comparar los datos de dos discos. La idea es seleccionar un
determinado sector de inicio y empezar a comparar con otros sectores del otro disco.
Figura 17. Comparación de datos de los discos
90
Cuando seleccionamos la opción Comparar del menú de inicio, nos salta esta
pantalla donde podemos seleccionar las dos unidades que queremos comparar, los
sectores de inicio de comparación, el número de sectores a comparar, el modo (con
pausa o sin pausa) y el archivo donde se guarda la información.
Una vez empieza la comparación, se abre un ventana donde se van a ver las
diferencia entre los sectores comparados.
Esta herramienta es muy eficaz para verificar que los datos que anteriormente se han
copiado coinciden con la unidad de origen.
9.4 La opción Buscar
La opción Buscar está diseñada para localizar cualquier dato en el todo el disco o
bien en una parte del mismo. El dato buscado se puede especificar mediante
números hexadecimales o bien caracteres del código ASCII. El programa especifica
donde se encuentran estos datos y la cantidad de veces que aparecen.
Figura 18. Búsqueda de datos en el disco
La información que tenemos que proporcionar al disco para hacer la búsqueda es: la
unidad donde se quiere buscar, el sector del cual empezará la búsqueda, el número
de sectores a tratar, el modo de búsqueda (hexadecimal o ASCII), el patrón que se
quiere localizar, el nombre del archivo donde se guardará la información del
procedimiento.
Cuando empieza el programa a buscar datos, nos muestra el sector donde se
encuentra la información y cuantas veces se encuentra ese dato en un sector
determinado.
91
9.4 La opción Configurar
A diferencia de las otras opciones, la opción Configurar cada dispositivo según las
preferencias del usuario. Nos permite determinar si el acceso es por la BIOS o bien
mediante comandos del disco duro, el modo, las repeticiones, y la opción de guardar
el procedimiento en un fichero
Figura 19. Las opciones de configuración
92
10 Manual de instalación y uso
10.1 Instalación del disco duro SATA
Los nuevos discos SATA son más simples de instalar que sus antecesores, los discos
IDE. En esta guía hacemos referencia a la instalación física del disco para que la
BIOS lo detecte y poder utilizar el programa.
Lo primero que haremos es apagar y desconectar la CPU de la alimentación y fijar
el disco en las ranuras del gabinete correspondiente. Luego, conectaremos el cable
de datos del disco SATA; este cable de datos es muy probable que sea provisto junto
al disco o junto con la placa base, sino es así, deberemos comprar un cable en
cualquier negocio de informática.
Una vez que tenemos el cable de datos del disco SATA, ubicaremos primero el
conector SATA en la placa base (se suele encontrar en grupos de 2 o 4 conectores) y
conectaremos allí uno de los extremos del cable (no importa cual extremo), el otro
extremo lo conectaremos a la parte posterior del disco (el conector es una pequeña
ficha con 7 pines). Por la forma que tiene la ficha solo tendremos una sola manera
de conectarlo.
Siguiendo con el proceso de instalación del disco SATA, ahora debemos conectar la
alimentación al disco; el conector de alimentación puede ser el tradicional o el
nuevo conector de alimentación SATA, este último es más pequeño que el anterior.
El conector en nuestra CPU se encuentra en los cables que salen de la fuente de
alimentación, y al igual que en el cable de datos solo lo podremos conectar de una
manera. Si el disco SATA solo tiene el nuevo conector de alimentación y la fuente
de alimentación no tiene estas fichas, tendremos que comprar un adaptador para
poder completar la instalación.
Figura 20. Cable de alimentación y de datos SATA
Si ya hemos fijado el disco y conectado los cables de datos y alimentación habremos
terminado de instalar el disco SATA en la CPU. Ahora, debemos encender la
computadora e ingresar a la BIOS para ver que el mismo haya sido detectado
correctamente.
93
10.2 Instalación del sistema operativo MS-DOS
Como ya se ha comentado anteriormente, el programa esta diseñado para trabajar en
MS-DOS. Por lo tanto, lo primero que se debe hacer es instalar este sistema
operativo. Actualmente, la manera más simple de trabajar con este sistema operativo
es instalarlo en un disco extraíble.
Antes de empezar la instalación debemos descargar los archivos de MS-DOS y la
herramienta HP_USB Storage Format Tool disponibles en la web.
Los pasos a seguir son:
1. Instalar el programa HP_USB Storage Format Tool.
3. Conectar el dispositivo USB.
4. Formatear el dispositivo USB utilizando la utilidad HP_USB Storage Format
Tool.
Figura 21. Ejecución de la herramienta HP_USB Storage Format Tool
Atención a la casilla que está debajo de “using DOS system files locates at:” se tiene
que poner el subdirectorio donde se ha descomprimido el sistema operativo DOS.
94
5. Copiar todos los archivos auxiliares del SO al dispositivo USB.
6. Para arrancar del dispositivo USB lo primero que se tiene que hacer es entrar en
el menú SETUP del ordenador en el momento de la arrancada. Posteriormente se
tiene que cambiar la prioridad de dispositivos en el menú HDD boost priority,
situado en la opción Advanced o Boost del menú Setup y colocar en primer lugar
el dispositivo USB.
7. Salimos del menú SETUP guardando los cambios y a partir de entonces, cada
vez que arrancamos con el dispositivo USB conectado, el ordenador arrancará
con el DOS.
Copiamos en Windows el ejecutable del programa al disco extraíble. Después
iniciamos el ordenador con el pen conectado, y una vez dentro del sistema operativo
ejecutamos el programa.
95
11 Presupuesto
El presupuesto necesario para el desarrollo de este proyecto es el siguiente:
Descripción
Unidades
Disco duro SATA 750GB
Cable SATA Datos+Alimentación
Memoria USB 1GB
1 Ud.
1 Ud.
1 Ud.
Precio
unitario
86,99 €/Ud.
5,86 €/Ud.
10,45 €/Ud.
Preparación de la memoria USB.
Horas de desarrollo del software
TOTAL
0,5 h
320 h
35 €/h
35 €/h
Precio total
86,99 €
5,86 €
10,45 €
17,50 €
11200 €
11320,80 €
Si se prevén unas ventas de 1000 unidades para amortizar el coste de desarrollo del
proyecto, el precio de venta de cada unidad de producto es el siguiente:
Amortización
Coste del disco duro por unidad
86,99 €
Coste del material por unidad
16,31 €
Coste de horas de preparación de la memoria USB por unidad
10,00 €
Coste de amortización del desarrollo del proyecto
11,20 €
SUBTOTAL
124,50 €
Si queremos obtener un beneficio del 10%
12,45 €
TOTAL
136,95 €
En caso de que el usuario disponga de un disco duro SATA y solo necesite la
memoria USB con el programa:
Amortización
Coste del material por unidad
10,45 €
Coste de horas de preparación de la memoria USB por unidad
10,00 €
Coste de amortización del desarrollo del proyecto
11,20 €
Si queremos obtener un beneficio del 10%
3,17 €
TOTAL
34,82 €
El coste de horas de preparación de la memoria USB por unidad asciende a 10,00 €,
debido a que para la preparación se ha tenido en cuenta que se puede hacer por una
persona con calificación de Ciclo Formativo de Grado Medio en informática.
Tomando como sueldo para esta calificación 20 €/h, y teniendo en cuenta que toda
la instalación se puede hacer en media hora, el precio final de la preparación de la
unidad USB es 10,00 €.
96
12 Conclusiones
Después de un cierto tiempo buscando información para realizar este proyecto, me
he dado cuenta que el programa realizado no está disponible en el mercado o al
menos no he podido encontrar algo parecido. Eso hace que esta utilidad tenga una
importancia especial vistas las ventajas que presenta tanto para usuarios con
conocimientos medio de informática como para programadores.
La ventaja más importante que tiene este programa es la gran mejora de la velocidad
de transferencia respecto al sistema operativo más utilizado (Windows). La última
prueba que se ha realizado ha demostrado que la transferencia se hace a la máxima
velocidad permitida por el hardware. Esto presenta un record en comparación con lo
que puede llegar a tardar la misma transferencia en la misma máquina trabajando
con Windows.
La idea de diseñar el programa para MS-DOS no está nada mal, pues a veces la
pérdida de datos de un disco duro suele ser por un fallo del sistema operativo o bien
por un archivo no seguro. MS-DOS nos permite acceder al disco para salvar datos
sin tener que recorrer al sistema operativo.
Desde el punto de vista del cliente, no solo interesa la calidad y la utilidad, sino que
el precio es vital para la decisión de adquirir o no un cierto programa. Este proyecto
ofrece una solución barata puesto que la utilidad preparada y instalada en una
memoria USB solo cuesta 34,82 €. El precio incluye unas ganancias del 10 %.
Se trata de un programa con una funcionalidad muy amplia. La más importante
quizá es la posibilidad de copiar toda la información de un disco a otro. Solo la
opción de modificación del disco puede tener mil y una utilidades. En general, se
trata de un programa que nos puede ser útil para infinidad de aplicaciones.
La realización de este proyecto me ha servido para perfeccionar mis conocimientos
de la programación en lenguaje C y también en Ensamblador. El dominio del
funcionamiento de los discos duros y de los modos de transferencia es un requisito
esencial para la realización de este proyecto. Este proyecto realmente presenta una
continuación del plan de formación de la ingeniería electrónica.
En resumen, se ha podido realizar un programa que permite el acceso a los discos
SATA y que permite múltiples opciones de gestión del disco. También se ha
conservado la compatibilidad con las funciones anteriores: gestión de los discos IDE
y disqueteras. Y finalmente se ha previsto un uso futuro del programa con discos de
más memoria de los actuales.
Por tanto, se han cumplido los objetivos iníciales.
97
13 Bibliografía y referencias
13.1 Referencias
[1]
Página Web http://es.wikipedia.org/wiki/Disco_duro 15/02/10
[2]
Página
Web
http://www.monografias.com/trabajos14/discosduros/discos
duros.shtml 15/02/10
[3]
Página Web http://es.wikipedia.org/wiki/Serial_ATA 15/02/10
[4]
Página Web http://www.serialata.org/ 18/02/10
[5]
Página Web http://www.ata-atapi.com/ 18/02/10
[6]
Página Web www.t13.org 09/03/10
[7]
Página Web www.t13.org/Documents/.../project/d1410r3b-ATA-ATAPI6.pdf 09/03/10
[8]
Página Web www.t13.org/Documents/.../docs2006/D1699r3f-ATA8- ACS.pdf
15/03/10
[9]
Página Web www.moodle.urv.cat/informatica_industrialII 1/07/10
[10]
Página Web http://html.rincondelvago.com/turbo-c.html 15/08/10
[11]
Página Web http://www.pccity.es/discos_duros_1029_pc.html?partn er=15&
nav=nav_superior 25/08/10
13.2 Bibliografía
[1]
Ceballos Sierra, Francisco Javier. El lenguaje de programación C. Madrid: RAMA, 2002
[2]
FUJITSU ESPAÑA. Un paseo por SATA, publicación Marzo 2004
98
14 Anexos
14.1 Comandos
La tabla siguiente contiene un resumen de los comandos compatibles con los discos
SATA.
(Continúa)
99
Figura 22. Tabla de comandos SATA
100
14.2 contenido de la respuesta al comando Identify device
(Continúa)
101
102
(Continúa)
103
104
Figura 22. Los 256 Words de respuesta al comando Identify device
105
14.3 Diferentes rutinas extraídas del código
A continuación vamos a ver algunas funciones del programa.
14.3.1 La función Disk_access48( )
Esta rutina se encarga de los accesos de discos SATA con direccionamiento 48-bit.
int disk_access48(u_char command, disk_Base *disk_base)
{
u_int n, m, local_error=0;
disk_irq.drive=disk_base->drive;
/* inicializaci¢n de la
estructura del driver */
disk_irq.nsectors=disk_base->nsectors;
disk_irq.lba=disk_base->lba;
disk_irq.buffer=disk_base->buffer;
disk_irq.feature=disk_base->feature;
disk_irq.cache_sectors=disk_base->piden->block_size;
disk_irq.io_base=disk_base->io_base;
disk_irq.command=command;
disk_irq.nirqs=1;
disk_irq.resto=0;
switch(command)
{
/* seg£n comando */
case READ_DMA_R48:
n=(disk_base->drive<2)?0:8;
/* se requiere actualizar el puntero a la tabla descriptora cada
vez */
if(!n) pci_io_write(disk_base->io_base+0x04, DTBA0, 4); /*
puntero a tabla descriptora canal 1 */
else
pci_io_write(disk_base->io_base+0x0C, DTBA1, 4); /*
puntero a tabla descriptora canal 2 */
pci_io_write(disk_base->io_base+0x00+n,
(u_long)((pci_io_read(disk_base->io_base+0x00+n,1)&0xFE)), 1); /* stop
DMA */
pci_io_write(disk_base->io_base+0x02+n,
(u_long)((pci_io_read(disk_base->io_base+0x02+n,1)|0x06)), 1); /*
reset status irq+error */
pci_io_write(disk_base->io_base+0x00+n,
(u_long)((pci_io_read(disk_base->io_base+0x00+n,1)|0x08)), 1); /*
lectura DMA */
break;
case WRITE_DMA_R48:
n=(disk_base->drive<2)?0:8;
/* se requiere actualizar el puntero a la tabla descriptora cada
vez */
if(!n) pci_io_write(disk_base->io_base+0x04, DTBA0, 4); /*
puntero a tabla descriptora canal 1 */
else
pci_io_write(disk_base->io_base+0x0C, DTBA1, 4); /*
puntero a tabla descriptora canal 2 */
pci_io_write(disk_base->io_base+0x00+n,
(u_long)((pci_io_read(disk_base->io_base+0x00+n,1)&0xFE)), 1); /* stop
DMA */
106
pci_io_write(disk_base->io_base+0x02+n,
(u_long)((pci_io_read(disk_base->io_base+0x02+n,1)|0x06)), 1); /*
reset status irq+error */
pci_io_write(disk_base->io_base+0x00+n,
(u_long)((pci_io_read(disk_base->io_base+0x00+n,1)&0xf7)), 1); /*
escritura DMA */
break;
case WRITE_MULTIPLE48: /* No existe en modo retry */
case READ_MULTIPLE48:
/* No existe en modo retry */
disk_irq.nirqs=(disk_base->nsectors/disk_irq.cache_sectors); /*
n§ irqs esperadas */
disk_irq.resto=disk_base->nsectors%disk_irq.cache_sectors;
/*
sectores restantes */
if(disk_irq.resto)
disk_irq.nirqs++;
break;
case WRITE_SECTORS_R48:
case READ_SECTORS_R48:
disk_irq.nirqs=disk_base->nsectors;
break;
/* n§ irqs esperadas */
case SET_MULTIPLE:
disk_irq.nsectors=disk_irq.cache_sectors; /* tama¤o del paquete
por irq */
break;
case INICIALIZAR:
disk_irq.command=IDENTIFY;
break;
}
if((local_error=x_disco48())!=0)
return(local_error);
/* llamada al manejador */
if(command==INICIALIZAR) /* captura de info a partir de IDENTIFY */
{
/*
Con el chip 82371EB, puede detectarse como existente un disco no
instalado,
incluso puede generarse la IRQ correspondiente. Para discriminarlo
analizamos
el sector devuelto por el comando IDENTIFY.
Se supone que si el disco no est instalado, el contenido de este
sector
coincidir en todos sus elementos enteros.
Cogemos un entero del campo del n§ de serie y lo comparamos con el
contenido del
campo del modelo. El contenido deber¡a ser id‚ntico si no existe el
disco.
*/
for(n=0; n<20; n++)
{
if(*((u_int*)disk_base->buffer+10) != *((u_int*)disk_base>buffer+27+n))
break;
}
107
if(n==20)
return(0xAA00);
/* disk not ready */
for(n=0; n<20; n+=2)
/* copia del n£mero de serie con giro(AH->AL;
AL->AH) */
{
*(disk_base->piden->n_serial+n)=*((u_char*)disk_base>buffer+20+n+1);
*(disk_base->piden->n_serial+n+1)=*((u_char*)disk_base>buffer+20+n);
}
for(n=19; n; n--)
/* colocaci¢n de fin de cadena ajustada */
if(*((u_char*)disk_base->piden->n_serial+n)!=0x20)
{
*((u_char*)disk_base->piden->n_serial+n+1)='\0';
break;
}
/* est justificado a la derecha y nos interesa a la izquierda
*/
for(n=0; n<20; n++) /* primer elemento */
if(*(disk_base->piden->n_serial+n)!=0x20) break;
m=n;
for(n=0; n<21-m; n++)
/* movimiento */
*(disk_base->piden->n_serial+n)=*(disk_base->piden>n_serial+n+m);
for(n=0; n<8; n+=2) /* copia de la revisi¢n firmware con giro */
{
*(disk_base->piden->r_firmware+n)=*((u_char*)disk_base>buffer+46+n+1);
*(disk_base->piden->r_firmware+n+1)=*((u_char*)disk_base>buffer+46+n);
}
for(n=7; n; n--)
/* colocaci¢n de fin de cadena ajustada */
if(*((u_char*)disk_base->piden->r_firmware+n)!=0x20)
{
*((u_char*)disk_base->piden->r_firmware+n+1)='\0';
break;
}
for(n=0; n<40; n+=2) /* copia del modelo con giro */
{
*(disk_base->piden->model+n+1)=*((u_char*)disk_base>buffer+54+n);
*(disk_base->piden->model+n)=*((u_char*)disk_base>buffer+54+n+1);
}
for(n=39; n; n--)
/* colocaci¢n de fin de cadena ajustada */
if(*((u_char*)disk_base->piden->model+n)!=0x20)
{
*((u_char*)disk_base->piden->model+n+1)='\0';
break;
}
disk_base->piden->block_ready=*((u_char *)disk_base>buffer+119)&0x1;
/* Se soporta transferencia de bloque? */
disk_base->piden->block_size=disk_base->piden->block_ready?\
*((u_char *)disk_base->buffer+118):0;
/* n§
sectores por irq */
108
// disk_base->piden->lba_ready=*((u_char*)disk_base->buffer+99)&0x02;
/* soporta modo LBA */
if(*(disk_base->buffer+53)&0x02)
/* PIO Mode advanced (3, 4,
...) */
{
if(*(disk_base->buffer+64)&0x01)
/* bit 1 */
disk_base->piden->pio_mode=3;
if(*(disk_base->buffer+64)&0x02)
/* bit 2 */
disk_base->piden->pio_mode=4;
}
else
/* PIO Mode old (0, 1, 2) */
disk_base->piden->pio_mode=*((u_int*)disk_base->buffer+51)>>8;
/* max modo PIO soportado */
disk_base->piden->udma_ready=(u_char)(*((u_int*)disk_base>buffer+53)&0x4); /* soporta modo ultra DMA */
if(disk_base->piden->udma_ready)
/* UDMA Modes 0, 1, 2, 3, 4 */
{
if(*(disk_base->buffer+88)&0x0100) disk_base->piden>udma_modes=0;
if(*(disk_base->buffer+88)&0x0200) disk_base->piden>udma_modes=1;
if(*(disk_base->buffer+88)&0x0400) disk_base->piden>udma_modes=2;
if(*(disk_base->buffer+88)&0x0800) disk_base->piden>udma_modes=3;
if(*(disk_base->buffer+88)&0x1000) disk_base->piden>udma_modes=4;
}
if(*(disk_base->buffer+83)&0x0400) disk_base->piden->bit_48=1;
else disk_base->piden->bit_48=0;
disk_base->piden->max_lba=*((u_long*)((u_char*)disk_base>buffer+120)); /* sector m s alejado */
if(disk_base->piden->max_lba>=0x0FFFFFFF) //si es el maximo
{
disk_base->piden->max_lba=*((u_long*)((u_char*)disk_base>buffer+200)); /* sector m s alejado (parte 1) */
disk_base->piden->max_lba2=*((u_long*)((u_char*)disk_base>buffer+204)); /* sector m s alejado (parte2) */
}
else disk_base->piden->bit_48=0;
disk_base->piden->mdma_modes=(u_char)(*((u_int*)disk_base>buffer+63))>>8; /* modos en multiword DMA soportados */
disk_irq.cache_sectors=disk_base->piden->block_size; /* para
READ/WRITE MULTIPLE */
}
return(local_error);
}
Código 1. Disk_access48( ) del archivo IDE_DRV1.C.
109
14.3.2 La función x_disco48( )
Esta función se ejecuta desde la rutina anterior. Su utilidad principal es enviar la
información de configuración al disco mediante la escritura en los registros.
u_int x_disco48(void)
{
u_int *code;
u_char
ready=SI,
busy=NO,
time_out=NO;
struct{
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
}err;
/* c¢digo de error */
/* disco listo */
/* disco ocupado */
/* l¡mite de tiempo */
AMNF
TK0N
ABRT
MCR
IDNF
MC
UNC
BBK
:1;
:1;
:1;
:1;
:1;
:1;
:1;
:1;
ERR
IDX
CORR
DRQ
DSC
DWF
DRDY
BUSY
:1;
:1;
:1;
:1;
:1;
:1;
:1;
:1;
/* registro de error a byte bajo */
/* b7 */
/* registro de estado a byte alto */
/* b15 */
u_int
canal,
base,
m_s;
code=(u_int*)&err;
*code=0;
disk_irq.flag=OFF;
irq14/irq15 */
/* canal 0/1: (IDE0, IDE1) */
/* direcci¢n base para acceso al disco */
/* master/slave */
/* variable de error */
/* no error */
/* este flag sirve para sincronizar con
m_s=(disk_irq.drive>1)?(disk_irq.drive-2):disk_irq.drive; /* indica si
master(0) • slave(1) */
base=(disk_irq.drive>1)?BASE_1:BASE_0;
/* disco secundario o
primario*/
canal=(disk_irq.drive>1)?CANAL_1:CANAL_0;
/* canal IDE0 IDE1 */
//printf("drive:%u ", disk_irq.drive);
//printf("status:%02X ",inportb(r_status2));
outportb(r_drive_head, (m_s?(0xF0):(0xE0)));/* LBA slave/master
*/
if(inportb(r_status2)&RDY)
/* si disk ready */
110
{
int z;
n_tics=10;
/* 10 * 55ms = 550 ms m ximo */
//n_tics=TICS;
/* tiempo de espera */
error=OFF;
while((inportb(r_status2)&BSY) && n_tics); /* espera no busy */
if(n_tics!=0)
{
//printf(" No busy ");
/* Programaci¢n de registros del tipo FIFO*/
//datos obtenidos de las dos variables LBA
outportb(r_sec_count, disk_irq.nsectorsprev);
outportb(r_sec_count, disk_irq.nsectors);
outportb(r_sec_number,Sec_numberprev);
outportb(r_sec_number, Sec_number);
outportb(r_cil_low, Cil_lowprev);
outportb(r_cil_low, Cil_low);
outportb(r_cil_high, Cil_highprev);
outportb(r_cil_high, Cil_high);
switch(disk_irq.command)
/* seg£n comando */
{
case SET_FEATURE:
outportb(r_feature, disk_irq.feature); /* establecimiento
de caracter¡sticas */
break;
case SET_IRQ:
outportb(r_int, IRQ_ENABLE);
return(0);
break;
case RESET:
outportb(r_int, RESET);
n_tics=TICS;
outportb(r_int, SET_IRQ);
/* validaci¢n de irqs */
/* reset */
/* tiempo de espera */
while((inportb(r_status2)&BSY) && n_tics!=0); /* espera
ready */
if(n_tics==0)
return(0xAA00); /* Drive not ready */
else
return(0);
break;
}
outportb(r_command, disk_irq.command); /* se env¡a comando al disco */
n_tics=10;
switch(disk_irq.command)
{
case WRITE_MULTIPLE48:
case
WRITE_SECTORS_R48:
while(((inportb(r_status2)&MASK_READY)!=READY) && n_tics);
/* espera data ready */
lba_w(); /* transferencia hacia el disco (.asm)*/
break;
111
case READ_DMA_R48:
case WRITE_DMA_R48:
pci_io_write(disk_irq.io_base+canal,
(u_long)(pci_io_read(disk_irq.io_base+canal,1)|0x01), 1); /* start DMA
*/
default:
while(!disk_irq.flag && n_tics);
/* espera conclusi¢n irq */
}
if(n_tics==0) time_out=SI; /* tiempo excedido */
}
else busy=SI; /* disco ocupado */
}
else ready=NO; /* disco no preparado */
disk_irq.flag=OFF;
*code=error;
/* error lo actualiza el manejador de IRQ */
if(!ready || busy || time_out) /* situaci¢n de error grave */
{
*code=(u_int)inportb(r_status1);
if((*code & 0x01)!=0)
*code=(*code<<8) | (u_int)inportb(r_error);
err.DRDY=ON; /* tiempo excedido (Drive not ready) */
outportb(r_int, SRST);
/* reset del disco */
n_tics=10; while(n_tics);
/* pausa 10*55=550 ms */
if(inportb(r_error)!=0x01) error=0x05; /* luego de reset r_error
es distinto */
outportb(r_int, IEN);
/* disk enable */
n_tics=5;
while(n_tics);
/* pausa 5*55=275 ms (se
requiere)*/
if(error=0x05) return(error);
}
//printf("error:%04X\t code:%04X\n",error, *code);
if(*code)
/* error particular */
{
inportb(r_status1); /* reset error */
if(time_out)
error=0xAA; /* Drive not ready */
else if(err.BBK) error=0x01; /* Bad sector */
/////////////////////
else if(err.UNC) error=0x10; /* Bad CRC/ECC */
else if(err.IDNF) error=0x04; /* Sector not found */
else if(err.ABRT) error=0x01; /* Bad command */
else if(err.TK0N) error=0x05; /* Reset fail */
else if(err.AMNF) error=0x02; /* Address mark not found */
else if(err.DRDY) error=0xAA; /* Drive not ready */
else if(err.DWF) error=0xCC; /* Write fault */
else if(err.CORR) error=0x11; /* CRC/RCC corectable */
else if(err.ERR) error=0xE0; /* Status error */
/* error=0x08 -> fallo DMA */
}
//getch();
return(error<<8);
}
Código 2. x_disco48( ) del archivo IDE_DRV1.C.
112
14.3.3 La función main( )
Como ya se sabe, esta rutina es la primera rutina q ejecuta el compilador. En este
programa se encarga de inicializar, presentar la información en pantalla y de llamar a las
diferentes rutinas para las diferentes opciones.
int main(int argc, char **argv)
{
int
fila=8,
/* coordenadas para presentaci¢n de info de
discos */
columna=4;
int
fin=NO,
option,
op=1;
'editar') */
/* flag: 1=> fin de bucle */
/* opci¢n seleccionadas del men£ */
/* opci¢n anterior (por defecto
if(analisis_arg(argc, argv)!=0)
return(1);
/* an lisis de argumentos */
if((n_discos=ini_disks())<0)
/* inicializaci¢n de drivers para
discos */
{
if(n_discos==-1)
printf("Error durante la detecci¢n de los discos\n");
else if((n_discos*=-1)>MAX_DISKS)
printf("Se detectan %d discos.\nEste software est
preparado para un m ximo de %d unidades.\n", n_discos, MAX_DISKS);
salir(fin_driver(1, p_disco[0].pbase));
}
ini_video_0(&color);
ini_window(p_disco);
ventanas */
ini_window_copy(p_disco);
ini_window_cmp(p_disco);
ini_window_config(p_disco);
ini_window_scan(p_disco);
gotoxy(1,25);
error */
printf("
/* presentaci¢n principal */
/* inicializa caracter¡sticas de las
/*
/*
/*
/*
ventanas
ventanas
ventanas
ventanas
para
para
para
para
COPY */
CMP */
CONFIG */
SCAN */
/* borrados de zona de mensajes de
");
PresInfoDiscos(columna, fila); /* presenta info sobre los discos */
while(!fin && !error && (option=menu_0(op-1))!=6) /* me£ principal */
{
gotoxy(1,25);
/* borrados de zona de mensajes de error
*/
printf("
");
switch(option)
{
case 0:
op=6;
/* se puls¢ ESC y situamos el ¡ndice en
salir */
continue;
case 1:
113
if(disk_edit()) fin=ON;
break;
case 2:
if(disk_copy(p_disco)) fin=ON;
discos */
break;
case 3:
if(disk_cmp(p_disco)) fin=ON;
discos */
break;
case 4:
if(disk_scan(p_disco)) fin=ON;
patrones en discos */
break;
case 5:
if(disk_config(p_disco)) fin=ON;
*/
break;
}
/* editor de discos */
/* copia de
/* comparaci¢n entre
/* b£squeda de
/* configuraci¢n
op=option;
if(!fin)
/* si no hay errores */
{
ini_video_0(&color);
/* presentaci¢n principal */
PresInfoDiscos(columna, fila);
/* presenta info sobre los
discos */
}
else
/* errores */
{
getch();
/* captura tecla */
printf("\n");
/* posiciona el cursor */
}
}
_setcursortype(_NORMALCURSOR);
textbackground(NEGRO); /* colores originales por defecto */
textcolor(BLANCO);
gotoxy(1,25);
if(!error)
/* borrados de zona de mensajes de error */
printf("
");
freeallmem_win();
ventanas */
/* libera posible memoria reservada para
salir(fin_driver(1, p_disco[0].pbase));
return(error);
}
Código 3. main( ) del archivo DISK_CAS.C.
114
/* condicones iniciales */
14.3.4 La rutina de atención a la interrupción
Esta rutina hecha en código Assembler se encarga de atender a la interrupción 14 del
disco. Hay otra rutina similar para la interrupción 15.
;--------------------------------------------------------------------; attn_irq14() rutina de atenci¢n a la interrupci¢n de disco duro
CANAL 0
;--------------------------------------------------------------------attn_irq14 PROC
FAR
push ds
push ax
mov
ax,seg disk_irq
mov
ds,ax
cmp byte ptr [disk_irq.NIRQS],0
jz
command_def14
;n§ de irqs acontecidas
dec byte ptr[disk_irq.NIRQS]
;irq-jnz irq_14_0
mov byte ptr[disk_irq.FLAG],ON ;indicaci¢n de evento (el disco
acab¢)
irq_14_0:
;
cmp byte ptr[disk_irq.COMMAND], WRITE_DMA
mov al, byte ptr[disk_irq.COMMAND];
cmp al, WRITE_DMA
jz command_def14
cmp al, WRITE_DMA_R
jz command_def14
cmp al, WRITE_DMA_R48
jz command_def14
;
cmp byte ptr[disk_irq.COMMAND], READ_DMA
cmp al, READ_DMA
jz command_def14
cmp al, READ_DMA_R
jz command_def14
cmp al, READ_DMA_R48
jz command_def14
;
cmp byte ptr[disk_irq.COMMAND], WRITE_MULTIPLE
cmp al,WRITE_MULTIPLE
;No existe este comando con retry
jz c_write_mul
cmp al,WRITE_MULTIPLE48
;No existe este comando con retry
jz c_write_mul
command_a:
;
cmp byte ptr[disk_irq.COMMAND], WRITE_SECTORS
cmp al, WRITE_SECTORS
jz c_write_sec
cmp al, WRITE_SECTORS_R
jz c_write_sec
cmp al, WRITE_SECTORS_R48
115
jz c_write_sec
;command_b:
;
cmp byte ptr[disk_irq.COMMAND], READ_MULTIPLE
cmp al, READ_MULTIPLE
;No existe este comando con retry
jz mod1
cmp al, READ_MULTIPLE48
;No existe este comando con retry
jz mod1
jnz command_c
mod1:
push cx
xor cx,cx
;dejamos en cx la cantidad de word a
transferir
mov cl, byte ptr[disk_irq.CACHE_SECTORS]
cmp byte ptr[disk_irq.NIRQS],0
jnz command_b0
cmp byte ptr[disk_irq.RESTO],0 ;sectores restantes
jz command_b0
;se leer n cache_sectors
mov cl, byte ptr[disk_irq.RESTO]
command_b0:
sal cx, 7
jmp c_read_multiple
;x128 doubles words
command_c:
;
cmp byte ptr[disk_irq.COMMAND], READ_SECTORS
cmp al, READ_SECTORS
jz c_rsectors
cmp al, READ_SECTORS_R
jz c_rsectors
cmp al, READ_SECTORS_R48
jz c_rsectors
jnz command_d
c_rsectors:
push cx
mov cx, 128
;doubles words a leer
jmp c_read_sectors
command_d:
;
cmp byte ptr[disk_irq.COMMAND], IDENTIFY
cmp al, IDENTIFY
jnz command_e
push cx
mov cx, 128
;doubles words a leer
jmp c_identify
command_e:
;
cmp byte ptr[disk_irq.COMMAND], INI_PARAM
cmp al, INI_PARAM
jnz command_f
jmp c_ini_param
command_f:
;
cmp byte ptr[disk_irq.COMMAND], SET_FEATURE
cmp al, SET_FEATURE
jnz command_def14
jmp c_set_feature
116
command_def14:
;*************
c_read_dma:
c_write_dma:
c_ini_param:
c_write_mul:
c_write_sec:
c_set_feature:
push dx
mov byte ptr[disk_irq.FLAG],ON ;indicaci¢n de evento (el disco
acab¢)
;seguir14:
mov error, OFF
;no error
;
cmp byte ptr[disk_irq.COMMAND], READ_DMA
cmp al, READ_DMA
jz def_dma14
cmp al, READ_DMA_R
jz def_dma14
cmp al, READ_DMA_R48
jz def_dma14
;
cmp byte ptr[disk_irq.COMMAND], WRITE_DMA
cmp al, WRITE_DMA
jz def_dma14
cmp al, WRITE_DMA_R
jz def_dma14
cmp al, WRITE_DMA_R48
jz def_dma14
jmp def_a14
def_dma14:
mov dx, word ptr[disk_irq.IO_BASE]
add dx, 08h
;start/stop DMA
in al, dx
and al,0feh
;stop DMA
out dx, al
mov dx, word ptr[disk_irq.IO_BASE]
add dx, 0Ah
;status DMA
in al, dx
mov ah, al
or al, 6
out dx, al
;reset irq + error
test ah, 02
jz def_a14
mov error, 8
;test b1
;si no error
;error de DMA
def_a14:
mov dx, R_STATUS
in
al, dx
;lectura de estado
test al,01
;error? b0=1 => error
jz
salir_def
;si no error
sal ax, 8
;R_STATUS pasa al byte alto
mov dx, R_ERROR
in al, dx
;R_ERROR pasa al byte bajo
mov error, ax ;variable global de error
117
salir_def:
mov dx,
mov al,
out dx,
mov dx,
out dx,
20h
20h
al
0A0h
al
pop dx
pop ax
pop ds
sti
iret
; salida
; fin 8259 master
; fin 8259 slave
;validamos irqs
;----------------------------------------------------------------;lee uno o m s sectores y los coloca a partir de [disk_irq+BUFFER]
;-----------------------------------------------------------------;El sector se lee a£n cuando pueda haber error
c_read_sectors:
c_identify:
c_read_multiple:
push di
push dx
push es
;
; salva registros efectados
mov error, OFF
;no error
mov dx, R_STATUS
in
al, dx
;lectura de estado
test al,01
;error? b0=1 => error
jz
leer
;si no error
sal ax, 8
;R_STATUS pasa al byte alto
mov dx, R_ERROR
in al, dx
;R_ERROR pasa al byte bajo
mov error, ax ;variable global de error
;leemos a£n cuando haya error
jmp fin_read ;salir
leer:
mov
mov
mov
cld
rep
;todo OK
es, [disk_irq+BUFFER+2]
;segmento del buffer
di, [disk_irq.BUFFER]
;offset del buffer
dx, R_DATA
;port de lectura IDE
insd
;bucle de lectura de doubles words
fin_read:
mov [disk_irq.BUFFER], di
mov
mov
out
mov
out
dx,
al,
dx,
dx,
dx,
pop
pop
pop
pop
pop
es
dx
di
cx
ax
20h
20h
al
0A0h
al
;actualizamos puntero
; salida
; fin 8259 master
; fin 8259 slave
; recupera registros
118
pop ds
sti
;validamos irqs
iret
; fin del manejador
;******************************************
attn_irq14 ENDP
; fin del procedimiento
Código 4. Attn_irq14 del archivo IDE_DRV0.asm
119
14.3.5 La función SetIdeDriver( )
Esta función se encuentra dentro del conjunto de rutinas de inicialización. Se encarga de
identificar los discos que forman parte del sistema y también de asignar el método más
eficiente y el comando adecuado para el acceso a los distintos dispositivos.
int SetIdeDriver(disco_info* disk)
{
int local_error;
/* error local */
prueba=0;
disk->ide=NO;
/* inicializamos */
if(driver==1)
/* propio, no BIOS */
{
if((local_error=disk_access(INICIALIZAR, disk->pbase))!=0)
{
//printf("La unidad %d no existe. error: %04x\n", m,
local_error);
//error=0; /* disk_access actualiza la variable global error */
return(local_error);
}
else
/* esta unidad IDE existe */
{
if(no_IDE_PCI) disk->pbase->piden->udma_ready=NO; /* no se puede
activar el modo UDMA */
*(disk->pbase->piden->model+19)='\0'; /* control de l¡mites de
cadena */
disk->unidad=disk->pbase->drive;
disk->ide=SI;
if(disk->sec_disco < disk->pbase->piden->max_lba)
{
disk->sec_disco=disk->pbase->piden->max_lba;
//disk->sec_disco2=disk->pbase->piden->max_lba2;
disk->cil=(disk->pbase->piden->max_lba/((disk->cab+1)*disk>sec))-1; /* cil l¢gicos */ //se puede selecionar
disk->sec_parti=(unsigned long)(disk->cil+1)*(disk>cab+1)*disk->sec-disk->sec;
}
}
/* Determinaci¢n del modo de operaci¢n m s eficiente
---------------------------------------------------- */
if(disk->pbase->piden->udma_ready)
{
if(ini_dma(disk->pbase))
{
gotoxy(1,25);
printf("Error en asignaci¢n de memoria");
//salir(fin_driver(0, disk->pbase));
error=1;
return(-1);
}
if(disk->pbase->piden->bit_48==1){
disk->pbase->c_read=READ_DMA_R48;
disk->pbase->c_write=WRITE_DMA_R48;}
120
//
else if(disk->pbase->piden->bit_48==0)
{
disk->pbase->c_read=READ_DMA;
disk->pbase->c_write=WRITE_DMA;
}
disk->driver=1;
/* driver propio*/
disk->defect_driver=1;
disk->modo=2;
/* DMA
*/
disk->defect_modo=2;
disk->retry=0;
/* no retry */
disk->defect_retry=0;
cprintf("Disco %u Protocolo: Ultra DMA/33 - /66", n);
}
else if(disk->pbase->piden->block_size>1)
{
if(disk->pbase->piden->bit_48==1){
disk->pbase->c_read=READ_MULTIPLE48;
disk->pbase->c_write=WRITE_MULTIPLE48;
}
else if(disk->pbase->piden->bit_48==0){
disk->pbase->c_read=READ_MULTIPLE;
disk->pbase->c_write=WRITE_MULTIPLE;
}
disk->driver=1;
/* driver propio */
disk->defect_driver=1;
disk->modo=1;
/* IRQ por bloque */
disk->defect_modo=1;
disk->retry=0;
/* no retry */
disk->defect_retry=0;
//
cprintf("Disco %u Protocolo: PIO %u sec/irq\n", n, disk->pbase>piden->block_size);
}
else
{
if(disk->pbase->piden->bit_48==1){
disk->pbase->c_read=READ_SECTORS_R48;
disk->pbase->c_write=WRITE_SECTORS_R48;
}
//
else if(disk->pbase->piden->bit_48==0){
disk->pbase->c_read=READ_SECTORS;
disk->pbase->c_write=WRITE_SECTORS;
}
disk->driver=1;
/* driver propio */
disk->defect_driver=1;
disk->modo=0;
/* IRQ por sector */
disk->defect_modo=0;
disk->retry=0;
/* no retry */
disk->defect_retry=0;
cprintf("Disco %u Protocolo: PIO 1 sec/irq", n);
}
}
return(error);
}
Código 5. SetIdeDriver( ) del archivo DISK_INI.C
121
14.3.6 La función de obtención del valor tecleado
Esta función está diseñada para obtener el valor tecleado por el usuario y guardarlo en
dos variables del tipo long (32 bits). Básicamente se usa para pasar el valor tecleado por
el usuario de un string a dos variables distintas.
Int Asciitolong2(char *str)
{
int i,stres[16],resta,por=1,bits[49],n=9,k,proxima=0;
unsigned int y;
int str[16];
clrscr();
for(i=14;i>-1;i--)
if(str[i])
{ n=i;
break;
}
k=0;
//obtencion del numero de caracteres tecleados
if(str[n]<2) proxima=1; //reduccion del numero
bits[k]=str[0]%2;
//obtencion del primer bit
k++;
while(n>-1)
{
for(i=n;i>-1;i--)
{
if(str[i]>=2)
{
stres[i]=str[i]/2;
resta=str[i]%2;
str[i-1]+=(resta*10);
por=1;
}
else
{
por*=10;
str[i-1]+=str[i]*por;
stres[i]=0;
}
}
por=1;
//divisiones / 2 ->conversion a binario
//si el resto es <2
for(i=0;i<14;i++) str[i]=stres[i]; //nueva operación de division
bits[k]=str[0]%2;
k++;
//obtencion del bit
if(proxima)
{
n-=1;
proxima=0;
}
//reduccion del numero de posiciones
if(str[n]<2) proxima=1;
}
122
for(i=48;i>-1;i--) //numero de bits obtenidos
if(bits[i])
{ k=i;
break;
}
for(y=0;y<32;y++) num1+=bits[y]*potencia(2,y); //variable 1
for(y=32;y<48;y++) num2+=((unsigned long)bits[y]*potencia(2,y32)); //variable 2
return(0);
}
Código 6. Asciitolong( ) del archivo MENUS.C
123
Descargar