logo titulo
anterior indice proximo

Partida e parada


No início deste manual, mostramos uma "visão de passarinho" do processo de carga do Linux. Vamos explorar esse assunto com mais detalhes, incluindo procedimentos extraordinários que se fazem necessários quando o sistema não carrega.

Durante o bootstrap, logo que a máquina é ligada (ou após um reset), o BIOS procura no primeiro setor do disco selecionado para carga (que pode ser modificado na edição das tabelas do BIOS, independentemente), um programa a executar, que será o nosso carregador (bootstrap loader). O mais usado com o Linux é o LILO, mas podemos até mesmo gravar um kernel em um disquete e usá-lo direto, sem carregador, o que não é recomendável,pois não poderíamos modificar os seus parâmetros de carga. Em um disco rígido, existe um setor de carga para cada partição criada, além do primeiro setor de toda a unidade, chamado master boot record.

O LILO pode ser configurado (como será visto mais adiante, neste mesmo capítulo) para carregar mais de um sistema operacional ou várias versões do mesmo sistema. É comum colocarmos várias imagens de kernels com configurações diferentes, por exemplo, e usar o LILO para escolher qual delas carregar. Para isso, devemos segurar uma das teclas Alt, Ctrl ou Shift, logo quando a mensagem LILO aparece na tela, ou ele carregará o primeiro kernel configurado.

Depois de carregado o kernel, normalmente comprimido, ele se expande antes de iniciar a sua execução (através de um pequeno programa colocado no início da imagem). Nesse momento, dependendo da forma que voce configurou o kernel, ele pode perguntar pelo modo de vídeo que será usado. Caso voce queira evitar essa pergunta, poderá configurar o kernel com rdev [29] para já entrar em um modo pré-determinado.

boot process

Em seguida, você verá uma série de mensages, emitidas pelo kernel, durante a detecção e configuração do seu hardware. Na minha máquina, por exemplo, surge o seguinte:

Console: 16 point font, 400 scans 
Console: colour VGA+ 80x25, 1 virtual console (max 63) 
pcibios_init : BIOS32 Service Directory structure at 0x000fdae0 
pcibios_init : BIOS32 Service Directory entry at 0xfdaf0 
pcibios_init : PCI BIOS revision 2.10 entry at 0xfdb11 
Probing PCI hardware. 
Calibrating delay loop.. ok - 59.80 BogoMIPS 
Memory: 31068k/32768k available (600k kernel code, 384k reserved, 716k data) 
Swansea University Computer Society NET3.035 for Linux 2.0 
NET3: Unix domain sockets 0.13 for Linux NET3.035. 
Swansea University Computer Society TCP/IP for NET3.034 
IP Protocols: ICMP, UDP, TCP 
Checking 386/387 coupling... Ok, fpu using exception 16 error reporting. 
Checking 'hlt' instruction... Ok. 
Linux version 2.0.30 (root@percproj) (gcc version 2.7.2) 
    #6 Tue Apr 28 15:19:15 EST 1998

Este conteúdo certamente será diferente na sua máquina, mas isso não importa. Note que a verão do meu kernel (2.0.30) parece um pouco antiga, mas voce não precisa correr para trocar de kernel a cada nova versão que surge. Evite especialmente as versões com o segundo número ímpar, pois são versões em desenvolvimento. O kernel estável atualmente está na versão 2.0.36, mas existem possibilidades do 2.2.0 surgir a qualquer instante. O pessoal trabalha duro para isso acontecer.

O próximo passo é o kernel montar o root filesystem (diretório /). Este pode ser modificado com rdev, ou como parâmetro fornecido ao LILO (root=/dev/<device>) durante a carga. Então o kernel inicia os processos swapper (processo 0) e init (processo 1), carregando o programa /sbin/init.

O processo init troca o estado do kernel para multi-tarefas, e lê o arquivo /etc/inittab, que conterá os sub-processos que ele deverá criar para tratar as linhas de terminal, locais ou via modem. Dessa forma, são inicializados pelo init, processos getty ou programa semelhante, e as linhas estão prontas para receberem conexões. Quando uma conexão é bem sucedida, voce verá no terminal a mensagem de login. O processo init pode também iniciar alguns daemons, dependendo do que contém os scripts que ele executa.

O init tem estados chamados níveis (levels), que definem a configuração do sistema. Os níveis são 0 a 6, s e S. Os processos a executar (criados como filhos de init) estão definidos em /etc/inittab, com o seguinte formato:

     id:nível:ação:processo

onde o id é uma sequência de 1 a 4 caracteres para dar nome a esta linha; o nível é um dos valor que discutimos logo acima; a ação é um dos valores: respawn, wait, once, boot, bootwait, off, ondemand, initdefault, sysinit, powerwait, powerfail, powerokwait, ctrlaltdel, kbrequest; finalmente processo é o processo a ser executado, normalmente um getty ou script de inicialização, mas outros comandos podem ser usados aqui.

Os scripts de inicialização são usualmente colocados no diretório /etc/rc.d, mas existe uma variação muito grande destes em cada distribuição Linux existente. Examinando atentamente /etc/inittab, podemos encontrar toda a sequência de scripts executada. Os níveis 0, 1 e 6 são reservados para parada do sistema (halt, nível 0), para a entrada em modo mono-usuário (single, nível 1), e para recarga do sistema (reboot, nível 6).

Veja a minha inittab, como exemplo:

id:4:initdefault:
si:S:sysinit:/etc/rc.d/rc.S
su:1S:wait:/etc/rc.d/rc.K
rc:23456:wait:/etc/rc.d/rc.M
ca::ctrlaltdel:/sbin/shutdown -t5 -rfn now
l0:0:wait:/etc/rc.d/rc.0
l6:6:wait:/etc/rc.d/rc.6
pf::powerfail:/sbin/shutdown -f +5 "A ENERGIA ESTÁ ACABANDO"
pg:0123456:powerokwait:/sbin/shutdown -c "ENERGIA DE VOLTA: FORÇA TOTAL"
ps:S:powerokwait:/sbin/init 5
c1:1235:respawn:/sbin/agetty 38400 tty1 linux 
c2:1235:respawn:/sbin/agetty 38400 tty2 linux 
c3:1235:respawn:/sbin/agetty 38400 tty3 linux 
c4:12345:respawn:/sbin/agetty 38400 tty4 linux 
c5:12345:respawn:/sbin/agetty 38400 tty5 linux 
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
# Minha linha discada, atendendo no modem (/dev/cua3) 
d3:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS2 vt100
x1:4:wait:/etc/rc.d/rc.4

No meu caso específico, o nível inicial (determinado pela linha com ação initdefault) é 4, e este nível por convenção ( no meu sistema ) é a entrada automática em X. Assim, o script rc.4 (última linha da listagem acima) será executado, e será sua responsabilidade inicializar o xdm, ou outra forma de entrar no X. Veja também que uso outra versão do agetty. Isto é muito questão de gosto. Existem uma meia dúzia de gettys diferentes, escolha o seu também!

criando um disquete de boot

Algumas vezes voce pode precisar de um boot de emergência, caso alguma coisa aconteça com a o LILO no seu disco rígido, se bem que isto com o uso normal dificilmente deve acontecer. Um procedimento simples é criar um disquete com boot direto no kernel (sem o LILO). No exemplo ao lado, no lugar de dd, um simples cp (copy) também pode ser usado. rdev é um programa que pode ser usado, entre outras coisas, para indicar aonde estará a raiz (diretório /) para configurar o kernel.
Troque /zImage pela sua imagem do kernel (pode ser vmlinuz, vmlinux, zimage, etc. Em algumas distribuições está no diretório /boot, sendo assim /boot/zImage ) e /dev/hda1 pela partição aonde está a raiz (execute mount para verificar).

~$ su

Password: *****

~# dd if=/zImage of=/dev/fd0

~# rdev /dev/fd0 /dev/hda1

configurando o lilo


A configuração do LILO é feita editando um arquivo. /etc/lilo.conf, e rodando o seu instalador (map installer), chamado (adivinhem?) lilo. O próprio LILO jamais será executado diretamente, a não ser na carga do sistema, afinal é para isso que ele existe. O map installer fica em /sbin/lilo, e utiliza-se do arquivo /etc/lilo.conf, além de vários arquivos do diretório /boot, o seu mapa de opções em /boot/map, e principalmente do /boot/boot.b, que é o segundo estágio do carregador, criado juntamente com o kernel.

Vejamos um exemplo do /etc/lilo.conf para carregar linux ou windows, escolhidos com Alt, Shift ou Ctrl na execução do LILO.
Este exemplo usa o MBR (master boot record) do primeiro disco rígido para armazenar o LILO, e é dado um time-out (retardo), parâmetro delay, de 3 segundos (30 décimos de segundo) para o usuário escolher o sistema a carregar.
boot = /dev/hda

delay=30

O parâmetro vga é passado ao kernel, informando qual o tipo da configuração de vídeo desejada. As opções são: normal (80x25), extended (80x50), ask (para pergeuntar ao usuário o modo desejado), ou um número com o modo de vídeo. O parâmetro ramdisk também é tratado pelo kernel.
O parâmetro message informa um arquivo onde se encontra a mesnagem (informativa) que deve ser enviada quando o usuário pressionar Shift após o aparecimento de "LILO" na tela.
vga = normal

ramdisk = 0

message = /etc/lilo.message

O parâmetro image indica o arquivo com a imagem do kernel; root informa o dispositivo que deve ser montado na raiz; label é um nome dado a esta imagem, e será usado na escolha manual do sistema a carregar. image = /zImage

root = /dev/hda5

label = linux

Mais uma imagem (opção) com a mesma raiz. Poderíamos também introduzir opções adicionais para o kernel adicionando a linha de comando: append=<string>. Para carregar um ramdisk, podemos fazer ramdisk=<size> e initrd=<arquivo com a imagem do ramdisk>. image = /zImage-exp

root = /dev/hda5

label = linux-exp

O LILO pode ser usado também para carregar outros sistemas operacionais, colocando other=<partição com o outro OS> e table=<disco com a tabela de partição>. Aqui, msdog é o nome "carinhoso" do MsDos! other = /dev/hda1

table = /dev/hda

label = msdog

como os scripts configuram o sistema


Já mostramos que o processo init executa scripts definidos no arquivo /etc/inittab. Mas onde estão esses scripts? Depende da distribuição que voce esteja usando. O diretório padrão para a localização desses scripts é o /etc/rc.d, mas a organização daí por diante depende muito de cada implementação. No RedHat e outras distribuições derivadas do mesmo, existe um arquivo "principal" /etc/rc.d/rc que recebe o nível do init como parâmetro e escolhe uma série de subdiretórios de arquivo com este nível (run-level).
No Slakware e no Plug-and-Play Linux (da Yggdrasil), por exemplo, todos os scripts estão no mesmo diretório /etc/rc.d e a terminação (rc.0, rc.1, etc.) determina o nível ou run-level do sistema. Este tipo de setup, entretanto, não é único, e voce deve procurar informações sobre isto na documentação da sua distribuição. Esta localidade (/etc/rc.d) é usada quando temos inicializaçãó compatível com o System-V, o que nem sempre é verdade, e existem outros esquemas (como o r2d2, por exemplo, que cria novos conceitos de configuração bem mais interessantes) não oficialmente suportados por nenhuma distribuição.

Instalação de novos device drivers, devem estar preferencialmente no arquivo /etc/rc.d/rc.local, que é carregado somente no final do processo de boot, quando praticamente todos os outros dispositivos estão já definidos.

A maior diferença entre o inittab dado acima e o padrão do RedHat, é na execução dos scripts de níveis: o que está l0:0:wait:/etc/rc.d/rc.0 aqui, no RedHat seria l0:0:wait:/etc/rc.d/rc 0, pois todos os scripts neste último são iniciados a partir de rc <nível>, enquanto que no Slakware existe um script separado para cada nível (run-level).

nível RedHat Slakware As várias distribuições do Linux têm pequenas diferenças nos run-levels (níveis) que definem o estado do processo init. Os níveis reservados, evidentemente, são iguais, pois estes são determinados na implementação do programa /sbin/init, que é o mesmo. Existem uma tendência a padronizar esses scripts, mas no momento eles possuem estas pequenas discrepâncias.
2      multi-usuário sem file-sharing multi-usuário
3 multi-usuário com file-sharing e daemons multi-usuário
4 estado definido pelo usuário partida com X11 (xdm)
5 partida com X11 (xdm) multi-usuário

Para manutenção, algumas vezes o administrador precisa ter certeza que nenhum outro usuário está utilizando o sistema. Nestes casos é interessante ir para o nível 1 (single user) ou já carregar o sistema neste estado. Para carregar o sistema assim, forenecemos como parâmetro para o LILO a opção single ou emergency, mas se você já está com o sistema no ar, no modo multi-usuário, execute telinit 1 e o sistema irá para o nível 1. Esta situação de emergência é necessária, por exemploc, quando você irá executa fsck (filesystem check, já visto) manualmente, para corrigir problemas com os sistemas de arquivos. Dificilmente esta alternativa será necessária, contudo, pois durante a carga normal do sistema, fsck já é executado e corrige quase 100% dos problemas. Essa situação é mais provável acontecer quando estamos testando um novo kernel, experiental, ou na hipótese de uma falha de hardware no disco rígido.

Finalmente, observe que não é possível entrar no sistema no modo single sem a senha do root (superusuário). Isso seria uma quebra de segurança, portanto jamais esqueça a senha do root! Ou, pelo menos, deixe um disquete preparado para boot com outra partição root (ou mesmo com um ramdisk com uma imagem alternativa do diretório raiz), nos casos em que o arquivo /etc/passwd for danificado.

Não é boa prática desligar o sistema de qualquer maneira, pois muitos arquivos poderão estar abertos para escrita e terminais com alguns usuário logados no sistema. Existe o comando shutdown exatamente para isso. Ele executa uma parada programada do sistema, que pode ser: (1) imediatamente (opção now), (2) na hora programada (introduzindo hh:ss), (3) daqui a n minutos (+minutos), com opção para efetuar um reboot ou halt (parada total).

Alguns exemplos:

parada imediata
shutdown -h now
reboot (recarga) daqui a 5 minutos
shutdown -r +5
somente um alerta para os usuários
shutdown -k now
com uma mensagem personalizada para os usuários
shutdown -h +15 "O sistema sairá do ar daqui a 15 minutos.\
Obrigado pela compreensão."
cancela um shutdown em andamento
shutdown -c


rpragana
Sat Jan 9 19:16:36 EDT 1999