O BIOS e os Discos fixos


[Home] [Dissertação] [Biba] [Linux] [Conjugue] [br.ispell] [axw3] [uplink]

Lidar com winchesters em PCs às vezes é complicado. Das inúmeras dificuldades que surgem na prática, uma das mais chatas refere-se à identificação dos discos pelo BIOS, importante para questões de boot. Vamos descrevê-la através de dois exemplos.

Bootando pelo SCSI ao invés do IDE

Neste caso, sua máquina dispõe de dois winchesters, um SCSI e um IDE. Você deseja bootar pelo SCSI, num sentido "forte" a saber, se subitamente for necessário remover o IDE, o boot continuará funcionando de forma normal, sem necessidade de reconfigurar o loader após a remoção do IDE (essa situação ocorre quando a sua máquina possui apenas um disco SCSI, mas vez por outra é necessário instalar temporariamente um IDE).

O BIOS tenta sempre bootar ou pelo primeiro floppy, ou pelo primeiro disco fixo. Nos dois casos ele procede da mesma forma: carrega na memória o primeiro setor do disco (flexível ou fixo) e executa-o. No caso de um disco SCSI e outro IDE, o BIOS mapeia o IDE como 0x80 e o SCSI como 0x81. Assim, o disco de quem o BIOS lerá o MBR será o IDE e não o SCSI.

Uma primeira solução seria instalar um loader no MBR do IDE e outro no MBR do SCSI. O loader em uso normalmente seria o do IDE. Havendo necessidade de removê-lo, automaticamente o do SCSI passaria a ser usado.

Essa alternativa não é boa. A cada substituição do kernel, o loader teria que ser reinstalado duas vezes, e após a remoção do IDE, apenas uma vez, sendo que o controle disso seria um tanto complexo. Sequer entraremos em todos os detalhes envolvidos nesse caso porque parece-nos que há um procedimento menos complicado.

Uma segunda solução consiste em não informar o BIOS da presença do disco IDE. Para isso, basta não registrá-lo no CMOS. Assim o BIOS mapeará o SCSI como 0x80, e bootará a partir dele. Não haverá necessidade de alterar o /etc/lilo.conf, que poderia ser assim:

    boot=/dev/sda
    map=/boot/map
    install=/boot/boot.b
    prompt
    timeout=50
    image=/vmlinuz
        label=linux
        root=/dev/sda1
        read-only

Apesar de simples, há uma pequena complicação. O loader instalado no MBR do disco SCSI é um programa que, através do BIOS, terá que ler o kernel do Linux. Bem, esse programa não informa ao BIOS um nome como /dev/sda1, e sim um device number, que terá que ser 0x80. Entretanto, o instalador do loader (o programa /sbin/lilo), não sabe que o disco scsi, para o BIOS é 0x80.

De fato, o Linux detetou o IDE independentemente das informações do BIOS ou do CMOS, e por isso o /sbin/lilo "acha" que o disco SCSI é identificado pelo BIOS como 0x81. Assim, é necessário explicitar no lilo.conf esse fato:

    boot=/dev/sda
    disk=/dev/sda
        bios=0x80
    map=/boot/map
    install=/boot/boot.b
    prompt
    timeout=50
    image=/vmlinuz
        label=linux
        root=/dev/sda1
        read-only
Uma vez removido o winchester IDE, essa informação que adicionamos passará a ser redundante, no entanto não haverá nenhuma necessidade de removê-la no caso de futuras trocas do kernel.

Preparando um disco numa máquina auxiliar

Suponha que você dispõe de uma máquina Linux com um único disco, e deseja criar uma cópia dele para usar num segundo micro. Suponha também que os dois discos sejam IDE. O que está em operação é o master da controladora primária. O segundo você conectará como slave dessa mesma controladora, a fim de copiar para ele o conteúdo do primeiro.

Terminada a cópia, você terá que instalar um loader do Linux nesse segundo disco. Suponhamos que você queira usar LILO no MBR. Instalar LILO no MBR desse disco significa colocar no primeiro setor dele (o MBR) um programa (o loader) que será carregado na memória RAM pelo BIOS no processo de boot. Esse programa, uma vez em execução, irá carregar na memória o kernel do Linux e dispará-lo.

Na verdade, como o tamanho do MBR é reduzido (512 bytes), não é possível colocar nele um programa muito complexo. Duas limitações básicas que esse programa terá serão a incapacidade de lidar diretamente com o hardware (vai precisar do BIOS como intermediário), e a impossibilidade de desembaralhar no disco a estrutura do filesystem ext2 (ou de qualquer outro), a fim de identificar os setores físicos, um por um, em que o kernel está armazenado (vai precisar de uma lista pré-computada desses setores).

Do ponto de vista da configuração do LILO, os dois discos são chamados, nesse momento, de /dev/hda e /dev/hdb (para o BIOS, entretanto, eles são identificados como devices 0x80 e 0x81). Assim, você teria que instruir o instalador do LILO (o programa /sbin/lilo) a colocar no primeiro setor do disco /dev/hdb o loader, que por sua vez deverá carregar o kernel do próprio /dev/hdb.

O problema, entretanto, é que, na sua residência definitiva, esse disco não será o "segundo", mas o "primeiro". O LILO não tem como saber disso, por isso o programa que ele gravará no MBR do segundo disco irá tentar, através do BIOS, ler o kernel do device 0x81.

Para resolver esse dilema, o /sbin/lilo pode ser instruído de forma a que o loader a ser colocado no MBR do segundo disco tente acessar não o device 0x81, mas o 0x80. O arquivo de configuração /etc/lilo.conf minimal nesse caso seria:

    boot=/dev/hdb
    disk=/dev/hdb
        bios=0x81
    image=/vmlinuz
        label=linux
        root=/dev/hda1

Note que nessa altura existem dois arquivos /etc/lilo.conf, o do disco original e o da cópia. Estamos nos referindo ao da cópia! Além disso conviria incluir nele cláusulas úteis como "prompt" "timeout=xx", mas evitamos fazê-lo para chamar a atenção para aquilo que é o tema aqui. Além disso, uma vez movido esse disco para o seu destino (o outro micro), esse arquivo deverá ser alterado para a sua forma "normal", que seria

    boot=/dev/hda
    image=/vmlinuz
        label=linux
        root=/dev/hda1
Acima subentendemos que a partição root é a primeira (/dev/hda1). Assim, a instalação do loader seria feita da seguinte forma:
    # mount -t ext2 /dev/hdb1 /mnt
    # lilo -r /mnt

O que aconteceu aqui? a partição root da cópia foi montada em /mnt, e o instalador do lilo foi instruído para, antes de mais nada, executar um chroot para /mnt. Feito o chroot, todos os acessos ao filesystem tomarão /mnt como root, ao invés de /. Assim, a lista dos setores de que falamos acima será gravada no arquivo /mnt/boot/map, ao invés de /mnt/boot, e ela ser referirá ao kernel /mnt/vmlinuz, e não ao /vmlinuz, que, afinal, é o que desejamos.