Acceso a Datos del Disco Duro desde el Hardware

Puertos del disco duro:

0x1f0 a 0x1f7, con un total de 8 puertos.

Modos de operación:

  1. CHS: Especificar cabeza, cilindro y sector.
  2. LBA: Indicar el bloque lógico inicial y la cantidad de bloques.

Interacción con puertos:

in destino[al / ax], origen[dx / i8] ; Recibir del puerto
out destino[dx / i8], origen[al / ax] ; Enviar al puerto

Se elige ax o al según el ancho del puerto: al para 8 bits, ax para 16 bits.

Implementación de LBA28 para lectura

LBA28 emplea un valor de 28 bits para el número de sector lógico, soportando hasta 128 GB de almacenamiento.

Detalles de puertos:

  • 0x1f0: Puerto de 16 bits para transferencia de datos.
  • 0x1f1: Registro de estado de errores.
  • 0x1f2 a 0x1f7: Puertos de 8 bits.
  • 0x1f2: Cantidad de sectores a leer.
  • 0x1f3 a 0x1f6 (bits bajos): Dirección lógica inicial de 28 bits.
  • 0x1f6 (bits altos): Configuración de dispositivo y modo.
    • Bit 4: Selección de disco (0: principal, 1: secundario).
    • Bit 6: Modo de direccionamiento (0: CHS, 1: LBA).
  • 0x1f7: Comandos: 0x20 para lectura, 0x30 para escritura.
; Definiciones de constantes
BASE_PUERTO equ 0x1f0
MODO_LECTURA equ 0xe0 ; 0b11100000
COD_LECTURA equ 0x20
; Variables globales
InicioSector dd 2 ;
NumSectores db 1
leer_disco:
 ; Configurar número de sectores
 mov al, [NumSectores]
 mov dx, BASE_PUERTO + 2 ; dx = 0x1f2
 out dx, al
 ; Enviar los 16 bits inferiores de la dirección
 mov ax, [InicioSector]
 inc dx ; dx = 0x1f3
 out dx, al
 
 mov al, ah
 inc dx ; dx = 0x1f4
 out dx, al
 ; Enviar bits superiores de la dirección
 mov ax, [InicioSector + 2]
 inc dx ; dx = 0x1f5
 out dx, al
 
 mov al, ah
 mov ah, MODO_LECTURA ; Combinar selección de disco y modo en al
 or al, ah
 inc dx ; dx = 0x1f6
 out dx, al
 ; Emitir comando de lectura
 mov al, COD_LECTURA
 inc dx ; dx = 0x1f7
 out dx, al

Una vez enviados los parámetros, se espera la respuesta del disco a través del puerto 0x1f7.

El código de estado se analiza mediante los bits 7 y 3.

  • Bit 7: 1 indica ocupado, 0 indica disponible.
  • Bit 3: 1 indica preparado, 0 indica no listo.
 MASCARA_EST equ 0x88 ; 0b10001000
 ESTADO_OK equ 0x08 ; 0b00001000
 .esperar:
   in al, dx
   and al, MASCARA_EST
   cmp al, ESTADO_OK
 jnz .esperar

Posteriormente, se procede a la lectura de los datos.

En este caso, se lee un sector completo de 512 bytes usando transferencia por palabras.

mov dx, BASE_PUERTO
mov cx, 256
.leer_palabra:
 in ax, dx
 mov [ds:di], ax ; Dirección destino en ds:di, modificable según necesidad
 add di, 2
loop .leer_palabra

Uso de la extensión INT 13

Para emplear este método, se requiere una estructura de datos específica:

DescriptorBloque:
   TamDesc db 10h
   Reservado db 0
   NumBloques dw 0
   DesplBuffer dw 0
   SegBuffer dw 0
   DirBloqueBaja dd 0
   DirBloqueAlta dd 0

Campos importantes:

  • TamDesc: Tamaño fijo de 16 bytes.
  • NumBloques: Cantidad de sectores a transferir.
  • DesplBuffer y SegBuffer: Dirección completa del buffer destino.
  • DirBloqueBaja y DirBloqueAlta: Componentes de 64 bits del número de sector lógico.

Previamente, se verifica la disponibilidad de la extensión INT 13.

.check_ext:
   mov ah, 41h ; Función de verificación
   mov bx, 55aah
   mov dl, 80h
   int 13h
   cmp bx, 0aa55h
   jnz error_handler

Si la extensión es compatible, se realizan las operaciones de lectura y escritura.

.read_block:
   mov ah, 42h ; Función de lectura
   mov dl, 80h
   mov si, DescriptorBloque
   int 13h
   test ah, ah
   jnz error_handler

.write_block:
   mov ah, 43h ; Función de escritura
   mov dl, 80h
   mov si, DescriptorBloque
   int 13h
   test ah, ah
   jnz error_handler

Los errores se pueden gestionra de manera unificada mediante una rutina de manejo de excepciones.

Etiquetas: assembly x86 hard-disk BIOS INT13

Publicado el 7-16 02:42