ATA/IDE em Modo PIO
Um drive ATA (IDE) acessado em modo PIO (Programmed I/O), através das portas legadas 0x1F0–0x1F7, ainda é o ponto de partida mais comum para um primeiro driver de armazenamento, já que não precisa de configuração de DMA nem de estruturas de lista de comando alguma, diferente da interface AHCI documentada separadamente, que é o que qualquer drive exposto dessa forma de fato é em hardware construído nas últimas duas décadas: não sobra controlador físico só de PIO algum para ter como alvo, só hardware AHCI que um driver pode adicionalmente endereçar através de seu próprio mapeamento de registrador compatível com o estilo PIO legado.
Os registradores
Seção intitulada “Os registradores”O barramento ATA primário expõe oito portas de I/O consecutivas começando em 0x1F0, cada uma com um significado diferente dependendo de ser lida ou escrita.
#define ATA_DATA 0x1F0 // porta de dados de 16 bits#define ATA_ERROR 0x1F1 // leitura: código de erro do último comando#define ATA_SECCOUNT 0x1F2 // contagem de setores para o próximo comando#define ATA_LBA_LO 0x1F3#define ATA_LBA_MID 0x1F4#define ATA_LBA_HI 0x1F5#define ATA_DRIVE_HEAD 0x1F6 // seleção de drive + bits 24-27 do LBA#define ATA_STATUS 0x1F7 // leitura: status; escrita: comandoATA_DRIVE_HEAD seleciona qual dos dois drives que um controlador consegue endereçar (master ou slave, um bit nesse mesmo registrador) junto com os quatro bits mais altos de um endereço LBA de 28 bits, e ATA_STATUS também funciona como o registrador de comando na escrita: enviar um byte de comando aqui (0x20 para uma leitura de setor em PIO, por exemplo) é o que de fato faz o drive começar a agir sobre o que quer que os outros registradores acabaram de ser preenchidos com.
IDENTIFY
Seção intitulada “IDENTIFY”Antes de um driver poder ler ou escrever qualquer coisa com segurança, ele precisa saber o que de fato está conectado a um dado slot de drive, e se esse dispositivo é um disco ATA ou um dispositivo ATAPI (um drive de CD/DVD, mais comumente) falando um conjunto de comandos relacionado, mas distinto, através das mesmas portas. O comando IDENTIFY (0xEC) responde às duas perguntas de uma vez: emitido com ATA_SECCOUNT e os registradores de LBA todos zerados antes, uma leitura seguinte de ATA_STATUS retornando zero significa que nenhum drive está presente; já ATA_LBA_MID/ATA_LBA_HI retornando valores de assinatura específicos e não nulos (em vez do zero que um drive ATA deixaria ali) identifica o dispositivo como ATAPI, ponto em que um driver deveria emitir IDENTIFY PACKET DEVICE (0xA1) em vez de continuar com o comando específico de ATA. Uma resposta de IDENTIFY bem-sucedida são 256 words de dados lidas de ATA_DATA, codificando a contagem total de setores endereçáveis do drive, se ele suporta endereçamento LBA de 48 bits além do limite do próprio conjunto de registradores de 28 bits, e uma string de modelo legível por humanos, entre muitos outros campos dos quais um driver tipicamente só precisa de um punhado.
Lendo um setor: o ciclo de polling
Seção intitulada “Lendo um setor: o ciclo de polling”Uma leitura em PIO não tem sinal de conclusão baseado em interrupção ou DMA por padrão; o driver em vez disso sonda ATA_STATUS num loop apertado, observando dois bits específicos: BSY (bit 7), definido enquanto o drive está ocupado processando o comando internamente, e DRQ (bit 3), definido assim que o drive tem dados prontos, esperando em seu próprio buffer interno para o host de fato ler.
void ata_wait_ready(void) { while (inb(ATA_STATUS) & 0x80) { } // espera BSY limpar}
void ata_read_sector(uint32_t lba, uint16_t *buffer) { outb(ATA_DRIVE_HEAD, 0xE0 | ((lba >> 24) & 0x0F)); outb(ATA_SECCOUNT, 1); outb(ATA_LBA_LO, lba & 0xFF); outb(ATA_LBA_MID, (lba >> 8) & 0xFF); outb(ATA_LBA_HI, (lba >> 16) & 0xFF); outb(ATA_STATUS, 0x20); // comando READ SECTORS
ata_wait_ready(); while (!(inb(ATA_STATUS) & 0x08)) { } // espera DRQ
for (int i = 0; i < 256; i++) buffer[i] = inw(ATA_DATA); // 256 words = 512 bytes}Assim que DRQ se define, exatamente 256 words de dezesseis bits, o equivalente a um setor no tamanho padrão de 512 bytes, precisam ser lidas de ATA_DATA nessa mesma sequência apertada, já que o buffer interno do drive espera ser esvaziado por completo antes de reportar prontidão para o que quer que venha em seguida: ler menos de 256 words e seguir para um comando diferente deixa o estado do buffer do drive fora de sincronia com o que o driver acredita ter de fato sido transferido.
Notas de implementação
Seção intitulada “Notas de implementação”Todo acesso de registrador nesse esquema custa uma viagem completa de ida e volta de I/O de porta, e os dados de todo setor adicionalmente precisam passar pela CPU uma word de cada vez via ATA_DATA, em vez de um motor de DMA movendo-os diretamente entre o drive e a memória da forma que o AHCI faz; essa é precisamente a limitação de desempenho que motivou o modelo de comando baseado em DMA do AHCI, e o PIO continua útil principalmente como um caminho simples e sem dependências para conseguir uma primeira leitura funcionando, não como um design que se espera que um kernel continue usando depois que I/O básico de disco já está confirmado correto. Um driver visando tanto o barramento primário (faixa 0x1F0) quanto o secundário (convencionalmente faixa 0x170, com um layout de registrador análogo) precisa rastrear o estado de BSY/DRQ independentemente por barramento, já que os dois barramentos, e os até dois drives em cada um, não compartilham status entre si apesar da semântica de registrador superficialmente idêntica.
Referências
Seção intitulada “Referências”- ^ T13 Technical Committee, ATA/ATAPI Command Set (ACS): a especificação formal do conjunto de comandos e do layout de registrador descrito acima.
Ver também
Seção intitulada “Ver também”- AHCI: o sucessor baseado em DMA que resolve diretamente a limitação de desempenho do polling do PIO, e a única interface que hardware moderno fisicamente expõe.
- Rede: um modelo de driver contrastante, construído em torno de anéis de descritor em vez de polling por comando.
- Controlador de Disquete: um driver de armazenamento ainda mais legado, compartilhando a abordagem baseada em polling e em nível de registrador deste artigo.