Estudo Linux 001: Inicialização do Linux e Bootloaders

 

Introdução ao Processo de boot  e startup do Linux

Já falamos resumidamente sobre como ocorre a inicialização em outro artigo: Boot – Como o Linux é Iniciado

Também falamos sobre sistema de arquivos nesse outro artigo: FAT32, Ext, Ext2, Ext3, Ext4, btrfs.. Qual Sistema de Arquivos Escolher?

Há duas sequências de eventos requeridos para iniciar o Sistema Operacional Linux: boot e startup.

boot

O boot começa quando a gente liga o computador e tem sua etapa finalizada quando o kernel é iniciado e o systemd carregado.

startup

O processo de startup se inicia após o kernel e o systemd serem iniciados na etapa de boot e termina quando o sistema estiver totalmente pronto.

 

Sequência Completa de Inicialização

 

É bom observar que a BIOS foi substituída pelo UEFI e o MBR pelo GPT. Mas, para aprendizado usaremos a BIOS e MBR para exemplos.

Segue abaixo sequência ilustrada

sequência do boot no linux

A imagem acima é um pouco antiquada, segue ilustração mais atual

Praticamente as imagens são parecidas só que, na segunda, ao invés de init, temos o systemd e targets. Clique aqui e veja nosso artigo a respeito.

Vamos falar sobre cada uma das etapas acima:

 

BIOS

 

“Qualquer usuário pode acessar a BIOS e configurá-la. Geralmente teclamos F2 ou Del assim que apertamos o botão “power on” para ligarmos  o computador”.

Essa etapa na verdade não tem nada a ver com o Linux; está relacionada com o hardware e é uma etapa idêntica para qualquer sistema operacional, seja ele linux, windows.

Quando apertamos o botão “ligar” a BIOS(Basic I/O System ou Sistema Básico de Entrada/Saída) entra em ação com um evento chamado POST(Power On Self Test ou Auto-teste de Inicialização)  que faz um checagem no hardware. Se algum hardware estiver com problema irá ocorrer uma falha do POST e o sistema operacional(Linux, widnows…) será impedido de iniciar.

Após a checagem do POST a BIOS localiza e carrega o MBR.

A principal função da BIOS é carregar o MBR.

 

MBR

MBR significa Master Boot Record ou registro mestre de Inicialização.

Está localizado nos primeiros 512 bytes do disco e possui 3 partes:  Bootloader, tabela de partição e magic number.

 

  • Boot Loader: dos 512 bytes 446 estão ocupados pelo boot loader. Ele tem  a função de dizer ao computador como iniciar(boot). O bootloader é um pequeno programa que identifica a partição inicializável e redireciona o processo  de boot para essa localização.
  • Tabela de partição: Um dispositivo(HD, por exemplo) pode ser divido em várias partes e a essas partes damos o nome de partições. As informações sobre as partições do disco ficam dentro da tabela de partição do MBR. Essas informações são do tipo: tamanho, tipo, status. Um MBR pode ter até 4 partições primárias; no entanto, sem a tabela de partição  seria possível criar apenas uma partição e, assim, não conseguiríamos instalar mais de dois Sistemas Operacionais(windows e linux em dual boot, por exemplo), ou termos mais de um sistema de arquivos(Ext4, ntfs, zfs…) instalado.
  • Magic Number: Esse “número mágico”  fica no final do MBR e ocupa apenas 2 bytes. O Magic  Number serve para indicar se o MBR está válido(OK) ou com falha. Ele só armazena valor em Hexadecimal; o valor AA55 classifica o MBR como válido. Um valor inválido indica a falta de MBR ou que ele está corrompido.  Esses valores são críticos e indica se o sistema irá inicializar ou não. Uma observação importante é que o valor hexadecimal, conforme dito acima, é representado pelo valor 0xAA55 ou AA55h, mas quando visto por meio de um programa de edição esse valor irá ser exibido como: “55 AA”

A função principal do MBR é localizar e carregar o bootloader(nesse caso, o GRUB)

 

GRUB

GRUB é o boot loader usado em sistemas Linux e semelhantes.

GRUB significa “grande gerenciador de inicialização unificado(Grand Unified Boot Loader)”. Antigamente existia o bootloader chamado Lilo para Linux.

No windows se usava o NTLDR e agora é usado o BOOTMGR. O Arquivo de configuração do NTLDR era o boot.ini. O arquivo de configuração do BOOTMGR é o binário BCD. Como BCD é um binário ele não pode ser editado diretamente como texto, assim existem alguns programas para alterá-lo, como: bcdedit.exe e EasyBCD.

GRUB substituiu o Lilo. Em 2002 o GRUB2 veio como versão melhorada do GRUB, então o GRUB foi renomeado oficialmente para “GRUB Legacy” e o GRUB2 passou a ser chamado de epenas GRUB.

O GRUB é tão poderoso que ele aparenta ser muito mais um mini Sistema Operacional do que simplesmente um bootloader.

A função do bootloader é deixar o computador capaz de encontrar o Kernel e carregá-lo na memória ram.

Essa é a tela do GRUB que aparece logo ao ligar meu computador com Ubuntu

 

Abaixo tela do GRUB no CentOS. Nesse caso há mais de um kernel instalado. Isso é bom, pois se durante alguma atualização de kernel ou instalação de módulos o sistema for comprometido poderemos acessar uma versão mais antiga.

Na parte de baixo de das telas acima há alguns comandos para acesso e edição do GRUB.

Após iniciado o Sistema Operacional, podemos ter acesso ao arquivo de configuração do GRUB que fica em:

/boot/grub/grub.cfg

ou em

/boot/grub2/grub.cfg

 

O GRUB tem  3 estágios ou etapas: a 1, 1.5 e 3.

Etapa 1 do GRUB

Logo após a BIOS executar o POST(checagem de integridade das peças) ele percorre os discos/dispositivos conectados à procura de um Registro de Inicialização(boot record), o primeiro encontrado é carregado para dentro da memória.

Logo no início desse post anexamos uma imagem ilustrando o MBR e podemos ver que ele está localizado nos primeiros 512 bytes de um dispositivo. Dentro dos 446 bytes iniciais dos 512  está o bootloader que em nosso caso é o GRUB; após os 446 bytes temos a tabela de partição com 64 bytes e, finalizando, temos 2 bytes finais que guarda o “Magic Number”.

Dentro da parte do bootloader há um código chamado de bootstrap(em inglês bootstrap code). A função do bootstrap é apenas localizar a partição que contém em seu início um “registro inicializável”.

No Windows a partição que contém esse setor de boot  é chamada de “partição ativa” e é dentro dessa partição que está o windows que será iniciado. Apenas uma partição pode ser marcada como ativa por vez.

O registro inicializável(boot record) é tão pequeno que ele não entende sobre sistema de arquivos.

O espaço reservado no MBR para o código bootstrap são os primeiros 446 bytes e é representado pelo arquivo boot.img

elder@ubuntu2:~$ locate boot.img
/boot/grub/i386-pc/boot.img

 

Como dito acima, o boot record não entende sobre sistemas de arquivos, então o estágio 1.5 toma controle da situação.

 

Etapa 1.5 do GRUB

Se a etapa 1 acima é representada pelo arquivo boot.img, a etapa 2 possui o arquivo core.img

elder@ti:~$ locate  core.img
/boot/grub/i386-pc/core.img

core.img tem 25.389 bytes.

Quando falamos de setores no disco nós consideramos que cada setor tem 512 bytes. O MBR está localizado apenas no setor 0 do disco, por isso ele ocupa somente 512 bytes. A primeira partição começa apenas no setor 63, ou seja, temos “livres” o intervalo do setor 1 até o setor 62; um espaço com   31.744 bytes, como fiz esse cálculo? simples, multipliquei 62×512=31744 bytes.

o arquivo core.img está localizado nesse espaço e ocupa apenas 25.389 desses 31.744 bytes. Ainda sobram 6.355 bytes.  Então há um bom espaço disponível até chegarmos no início da primeira partição.

Nesse  espaço à mais do estágio/etapa 1.5 do GRUB há alguns drivers de sistemas de arquivos(ext4, ntfs, fat….) armazenados. Se a etapa 1 não entende Sistemas de Arquivos, a etapa 1.5 toma controle e já é capaz de lidar com isso.

 

A função do estágio 1.5 é começar a executar os drivers de sistemas de arquivos necessários para localizar os arquivos do estágio 2.

 

Etapa 2 do GRUB

Todos os arquivos da etapa 2 estão localizados dentro do diretório e subdiretórios em /boot/grub/

A etapa 2 não possui arquivo de imagem(boot.img e core.img) como as outras etapas anteriores. Pois a etapa 2 consiste de módulos do kernel que são  carregamos conforme a necessidade. Esses módulos ficam em /boot/grub/i386-pc/

A função da etapa 2 é carregar o kernel na memória ram e passar o controle do computador para ele.

O kernel e seus arquivos relacionados estão dentro da pasta /boot. Podemos identificar os kernel facilmente já que todos começam com a palava vmlinuz

elder@ubuntu:~$ ls -1  /boot
config-4.15.0-112-generic
config-4.15.0-47-generic
grub
initrd.img-4.15.0-112-generic
initrd.img-4.15.0-47-generic
System.map-4.15.0-112-generic
System.map-4.15.0-47-generic
vmlinuz-4.15.0-112-generic
vmlinuz-4.15.0-47-generic

 

Vimos anteriormente que ao ligar o computador, o GRUB exibe em um menu a os kernels disponíveis

Bom… resumindo, a função do GRUB é carregar o kernel na memória ram.

KERNEL

Os kernels estão dentro da pasta /boot em um formato compactado e auto-extraível.

Quando um kernel é carregado na memória ele se auto-extrai, saindo da sua forma compactada, e começa a trabalhar. Assim que o kernel é carregado ele inicia o processo systemd. O systemd é o pai de todos os processos.

Acima mencionamos que toda a inicialização do Linux é dividida em duas partes:  boot e startup. Aqui se encerra o processo de boot e é começado o de startup.

 

O Startup

 

O processo de startup faz com que o Linux fique pronto para uso do usuário.

Systemd

O systemd é o principal agente nessa fase, ele é o pai de todos os processos e tem muito mais funções que o antigo init. Dentre essas funções: pode montar sistemas de arquivos, iniciar e parar serviços do sistema etc…

O systemd age da seguinte forma após o kernel iniciá-lo:

  1. Monta os sistemas de arquivos conforme especificado em /etc/fstab
  2. acessa arquivos de configurações dentro de /etc
  3. Ele analisa o arquivo /etc/systemd/system/default.target para saber em qual estado/target ele deve iniciar o sistema operacional. Algumas  dessas targets são multi-user.target que faz o computador iniciar com tudo menos a interface gráfica, rescue.target onde o sistema inicia apenas uma linha de comando para recuperação, graphical.target onde todo o sistema é carregado, inclusive a interface gráfica. Há também a target emergency.target que inicia apenas os serviços necessários para reparação de algum problema.
  4. Cada target possui suas dependências. systemd inicia essas dependências.
  5. Systemd também analisa  pastas do antigo init do SystemV(chamado também de SysV), se houver algum arquivo para ser inicializado dentro dessas pastas o systemd usa esses arquivos também.

 

Comparação entre SystemV e Systemd

Abaixo temos uma comparação do antigo SystemV(ou sysv) com o atual Systemd.

 

SystemV Runlevel systemd target systemd target aliases Descrição
  halt.target   Interrompe o sistema, sem desligá-lo.
0 poweroff.target runlevel0.target Interrompe o sistema, desligando-o
S emergency.target   Modo de manutenção ou single. Nenhum serviço é executado; Sistemas de arquivos não são montados. Este é o mais básico nível de operação  com apenas um shell de emergência, para interpretação de comandos, sendo executado no console principal para o usuário interagir com o sistema.
1 rescue.target runlevel1.target Um sistema básico que monta o sistema de arquivos  com os serviços mais básicos  e um shell(interpretador de comandos) de recuperação no console principal.
2   runlevel2.target Multiusuário, sem NFS mas com todos os outros serviços sem interface rodando.
3 multi-user.target runlevel3.target Todos os serviços sendo executados mas sem interface gráfica.
4   runlevel4.target Não usado.
5 graphical.target runlevel5.target multi-usuário com interface gráfica.
6 reboot.target runlevel6.target Reinicia o sistema
  default.target   Este target é sempre um alias(apelido) com um link simbólico para multi-user.target or graphical.target. systemd sempre usa default.targetpara iniciar o sistema. O  default.target nunca deve ter um alias(apelido) para halt.target, poweroff.target, ou reboot.target.

 

Eventos que o Systemd Executa até a Finalização do Processo de Startup

O Systemd trabalha com targets ao invés dos runlevels do antigo SystemV.

Segue abaixo um gráfico retirado do site man7.org.

                                                cryptsetup-pre.target
                                                             |
           (diversas montagens de API VFS                    v
            de baixo nível:                    (vários dispositivos cryptsetup...)
            mqueue, configfs,                                |    |
            debugfs, ...)                                    v    |
            |                                  cryptsetup.target  |
            |  (vários swap                                  |    |    remote-fs-pre.target
            |   devices...)                                  |    |     |        |
            |    |                                           |    |     |        v
            |    v                       local-fs-pre.target |    |     |  (Sistema de Arquivos de rede)
            |  swap.target                       |           |    v     v                 |
            |    |                               v           |  remote-cryptsetup.target  |
            |    |  (vários serviços de (várias montagens e  |             |              |
            |    |   baixo nível: udevd,  erviços fsck...)   |             |    remote-fs.target
            |    |   tmpfiles, random            |           |             |             /
            |    |   seed, sysctl, ...)          v           |             |            /
            |    |      |                 local-fs.target    |             |           /
            |    |      |                        |           |             |          /
            \____|______|_______________   ______|___________/             |         /
                                        \ /                                |        /
                                         v                                 |       /
                                  sysinit.target                           |      /
                                         |                                 |     /
                  ______________________/|\_____________________           |    /
                 /              |        |      |               \          |   /
                 |              |        |      |               |          |  /
                 v              v        |      v               |          | /
            (vários         (vários      |  (vários             |          |/
             timers...)      paths...)   |   sockets...)        |          |
                 |              |        |      |               |          |
                 v              v        |      v               |          |
           timers.target  paths.target   |  sockets.target      |          |
                 |              |        |      |               v          |
                 v              \_______ | _____/         rescue.service   |
                                        \|/                     |          |
                                         v                      v          |
                                     basic.target         rescue.target    |
                                         |                                 |
                                 ________v____________________             |
                                /              |              \            |
                                |              |              |            |
                                v              v              v            |
                            display-    (vários sistema   (vários sistema  |
                        manager.service     de serviços     de serviços)   |
                                |         requeridos para     |            |
                                |         UIs gráficos)       v            v
                                |              |            multi-user.target
           emergency.service    |              |              |
                   |            \_____________ | _____________/
                   v                          \|/
           emergency.target                    v
                                         graphical.target

O systemd tem como função iniciar serviços(programas) em paralelo, um serviço ao lado do outro. Os termos “paralelo e série” são muito empregados em informática. por exemplo, programas em paralelo rodam ao mesmo tempo e serviços em série rodam em sequência, isto é, um processo só é executado quando o que está à sua frente termina.

Observe acima as targets sysinit.target e basic.target. Praticamente todos os serviços passam por eles. Eles funcional como ponto de checagem. Ainda que o systemd tenha como prioridade e meta executar serviços em modo paralelo ainda há certos serviços e targets que devem ser executados antes de outros, dependem de outros. Toda essa dependência é gerida pelo systemd.

Voltando às targets sysinit e basic, elas funcionam como ponto de checagem e os serviços  acima delas não podem passar até estarem completas e aprovadas por esses pontos de checagem.

Dentro de sysinit.target todos os serviços são executados em paralelo: dispositivos criptografado, swap, udev, random seed… e só passam por sysinit.target quando completados.

dentro de basic.target, também, todos os serviços são executados em paralelo: timers, paths, sockets….., só passam por basic.target quando completados.

Após passar por sysinit.target e basic.target, perceba que o multi-user.target é sempre carregado para poder se chegar no graphical.target.

 

Conclusão

 

Discos são mais que apenas partições e conteúdos guardados. Há uma pequena parte do disco que é muito importante, o MBR ou master boot record que em português significa registro metre de inicialização. O está sendo substituído pelo GPT. Mas nos limitamos a falar sobre MBR nesse artigo.

O boot loader está dentro do MBR e é iniciado pela BIOS quando ligamos o computador.

O boot loader inicia o  kernel do linux e o kernel. O kernel inicia o systemd e esse se encarrega dos demais serviços.

Todo o processo de inicialização é dividida em duas etapas: boot e startup. O startup começa quando o systemd é iniciado.

 

Fontes: wikipedia, thegeekstuff, opensource.com, mbrwizard.com, neosmart.net, man7.org,

Leitor voraz e um dos administradores do GNU/Linux Brasil no Whatsapp, facebook, youtube e nesse dito site: www.gnulinuxbrasil.com.br

One Comment to “Estudo Linux 001: Inicialização do Linux e Bootloaders”

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *