Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

05 - Passagem de Parâmetros ao Kernel (linux, initrd)

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

1. O Contrato Arquitetural: Linux Boot Protocol

O ato de carregar um sistema operacional moderno não se resume a copiar um arquivo binário para a memória RAM e instruir o processador a executar a primeira instrução. O Kernel Linux exige um estado computacional rigorosamente coreografado antes de assumir o controle. Esta especificação, conhecida formalmente como Linux Boot Protocol (documentada historicamente em Documentation/x86/boot.txt na árvore do kernel), dita a Interface Binária de Aplicação (ABI) exata que o bootloader (como o GRUB2) deve respeitar.

No cerne deste protocolo está uma estrutura de dados de software chamada Zero Page (formalmente definida em linguagem C como struct boot_params). Esta estrutura de 4096 bytes atua como a certidão de nascimento do sistema operacional. O GRUB2 tem a obrigação arquitetural de alocar espaço na memória RAM, instanciar a Zero Page e preenchê-la meticulosamente com metadados cruciais do hardware, incluindo o mapa físico de memória detectado pelo firmware (tabela e820 ou UEFI Memory Map), os parâmetros da tela de vídeo (VGA/VESA/GOP) e, mais criticamente, os ponteiros de memória que indicam onde a linha de comando do kernel e a imagem do sistema de arquivos temporário (initrd) foram injetados.

Sem a construção matemática perfeita da Zero Page, o kernel operaria "cego" e sofreria um colapso imediato (early panic) logo nos primeiros microssegundos de execução.

2. A Diretiva linux: Carga e Montagem do Payload

No arquivo de configuração grub.cfg ou no Normal Shell interativo do GRUB, a instrução primordial de inicialização é a diretiva linux (ou suas variantes linux16 para ambientes legados e linuxefi / linux sob UEFI). Esta diretiva invoca um módulo complexo do GRUB responsável pelo tratamento da imagem compilada do kernel (geralmente nomeada como vmlinuz).

O processo interno executado pela diretiva linux obedece aos seguintes passos lógicos em nível de máquina:

  1. Leitura do Setup Header: O GRUB lê os primeiros blocos do arquivo vmlinuz. Em arquiteturas x86, este arquivo é construído no formato bzImage. O GRUB extrai o Setup Header (localizado no offset 0x01F1), que informa a versão do protocolo de boot exigida pelo kernel e se o binário suporta realocação de memória (KASLR - Kernel Address Space Layout Randomization).

  2. Alocação de Memória Física: Dependendo das permissões do Setup Header, o GRUB requisita uma janela de memória RAM contígua (frequentemente a partir de 1MB físicos ou randomicamente em ambientes KASLR sob UEFI) e copia o payload protegido do kernel bit a bit do dispositivo de armazenamento para esta região.

  3. Alocação do Command Line Buffer: A string de texto plano fornecida após o caminho do arquivo (ex: root=UUID=... ro quiet splash) é tratada separadamente. O GRUB aloca um espaço dedicado em RAM estritamente para hospedar essa cadeia de caracteres em formato ASCII, terminada com um caractere nulo (\0).

  4. Atualização dos Ponteiros na Zero Page: O endereço físico absoluto do buffer que contém a string de parâmetros é calculado e gravado no campo hdr.cmd_line_ptr da Zero Page. O GRUB valida que o tamanho da string não ultrapassa o limite arquitetural do kernel (historicamente 2048 bytes, expandido em kernels modernos para 4096 bytes).

3. A Semântica da Kernel Command Line

A string de parâmetros construída pelo bootloader não é processada pelo GRUB; ela é passivamente repassada ao Kernel. Quando o kernel assume a execução, muito antes de ativar escalonadores de processos ou sistemas de arquivos completos, ele invoca funções rudimentares de processamento de texto (como a rotina parse_args) no microcódigo inicial.

A Kernel Command Line é o vetor de controle supremo do administrador sobre o comportamento profundo do núcleo. Os argumentos são avaliados através de macros predefinidas (como __setup ou early_param no código-fonte do C do Linux):

  • Diretivas de Espaço do Kernel: Parâmetros como acpi=off, nomodeset, ou intel_iommu=on interagem com os drivers em nível mais primitivo. Se o administrador injetar mitigations=off, o kernel ignora os reparos de segurança de hardware (como Spectre e Meltdown), alterando o mapeamento das tabelas de página globais.

  • Diretivas do Espaço de Inicialização (Init): Parâmetros como root=, rootflags= e init= não são consumidos primariamente pelas entranhas do kernel. Eles são lidos e utilizados posteriormente para montar a árvore virtual do VFS ou são repassados ao processo PID 1 (systemd ou sysvinit) que, através do /proc/cmdline, extrairá as diretivas necessárias para gerenciar os targets do espaço do usuário.

4. A Diretiva initrd: Injeção do Sistema de Arquivos Temporário

A diretiva initrd (ou initrdefi) é funcionalmente acoplada e obrigatoriamente declarada após a diretiva linux. O arquivo invocado (geralmente nomeado initrd.img ou initramfs-linux.img) é um arquivo cpio compactado que contém os módulos de device drivers críticos, sem os quais o kernel seria incapaz de compreender a infraestrutura física de disco (como drivers NVMe, controladores RAID e bibliotecas de descriptografia LUKS) para alcançar o parâmetro root= especificado anteriormente.

Como o kernel isolado não pode ler discos antes de carregar os próprios drivers (paradoxo do ovo e da galinha), o GRUB atua como provedor. O processamento da diretiva initrd segue uma lógica rigorosa de injeção de memória:

  1. Alocação no Extremo Superior da RAM: O GRUB lê todo o arquivo compactado initrd.img diretamente do disco. Diferente do kernel, que é alocado próximo à base de 1MB a 16MB, o GRUB geralmente tenta alocar o initrd no limite superior da memória física disponível (High Memory) para evitar colisões ou fragmentação dos blocos iniciais cruciais.

  2. Registro de Extensão: O tamanho exato do arquivo injetado (em bytes) é meticulosamente calculado.

  3. Mapeamento de Hardware (Handshake): O GRUB escreve as coordenadas de onde este payload reside na RAM em dois registradores de software dentro da Zero Page do Kernel:

    • hdr.ramdisk_image: Recebe o endereço físico base de 32-bits de onde o initrd começa. (Em sistemas operando com mais de 4GB, campos estendidos como ext_ramdisk_image são preenchidos).

    • hdr.ramdisk_size: Recebe o comprimento estrito do bloco lógico.

Com essas informações preenchidas pelo GRUB, o kernel conseguirá extrair o arquivo compactado diretamente da RAM em um sistema virtual (tmpfs), montando o "Root temporário" independente de leituras de barramentos físicos de disco.

5. O Clímax Arquitetural (A Transição e o Handover)

Uma vez que o GRUB tenha validado a carga via as diretivas linux e initrd, o usuário não visualiza nenhum processamento adicional. A execução do comando mestre final boot (geralmente embutido no script do menuentry) desencadeia a ruptura arquitetural definitiva, encerrando a vida útil do bootloader e inicializando o Kernel.

Este é o momento do Handover. As condições elétricas e lógicas do processador central (CPU) são brutalmente modificadas para que o Linux não sofra interferências. Em plataformas x86_64 sob UEFI, o processo é o seguinte:

  1. Chamada ExitBootServices(): O GRUB se comunica com o firmware UEFI e formalmente o instrui a desligar todos os drivers de disco, serviços de rede e temporizadores da fase de boot (Boot Services). O firmware transfere a custódia do mapa de memória físico de forma definitiva para o kernel.

  2. Higienização de Interrupções: A instrução de máquina CLI (Clear Interrupt Flag) é acionada. O processador para de escutar teclado, mouse ou temporizadores, blindando o kernel de interrupções assíncronas de hardware indesejadas até que a sua própria tabela de descritores de interrupções (IDT) esteja instaurada.

  3. Preparação de Registradores: O estado dos registradores da CPU é sobreposto. A título de exemplo arquitetural no padrão Linux-x86, o registrador ESI/RSI é imperativamente carregado com o endereço físico onde a Zero Page (struct boot_params) foi salva na RAM.

  4. O Salto Definitivo (JMP): O ponteiro de instrução da CPU (RIP) é redirecionado para o endereço do ponto de entrada do kernel (o cabeçalho executável em memória do arquivo do vmlinuz descompactado).

A partir deste exato milissegundo, a memória outrora ocupada pelas linhas de código dinâmicas do GRUB será tratada apenas como "dados sujos" remanescentes em RAM, pronta para ser reciclada pelo subsistema do kernel. A máquina agora está operando estritamente sob as leis e lógicas de código monolítico do Linux.