04 - Parâmetros de Boot do Kernel (console, root, quiet, splash)
video: https://youtu.be/... no frontmatter da nota.A linha de comando do kernel (Kernel Command Line ou cmdline) é o mecanismo arquitetural definitivo de injeção de estado estático no núcleo do Linux. Como o kernel (operando em Ring 0) precisa inicializar o hardware, mapear a memória e orquestrar a transição para o espaço do usuário antes de ter acesso a qualquer sistema de arquivos ou arquivo de configuração (/etc), ele depende inteiramente de uma string ASCII passada a ele pelo bootloader durante o milissegundo do hand-off de execução.
Esta string não é meramente um conjunto de variáveis globais; ela é a fundação que dita a topologia de inicialização, mitigação de falhas de CPU, comportamento do sistema de log interrupções de hardware (APIC) e os limites do gerenciador de memória (MMU).
1. A Estrutura de Passagem de Parâmetros e o Zero Page
O bootloader (como o GRUB2, systemd-boot ou EFISTUB) não escreve os parâmetros de boot em um arquivo. Na arquitetura x86/x86_64, ele obedece ao "Linux Boot Protocol", que define uma região de memória específica conhecida como Zero Page (historicamente na estrutura boot_params).
O bootloader carrega a string ASCII bruta (limitada a 2048 ou 4096 bytes, dependendo da compilação, definida por COMMAND_LINE_SIZE) em um endereço de memória física alocado e passa o ponteiro para esse endereço no cabeçalho do bzImage (especificamente no campo cmd_line_ptr no offset 0x228).
Quando a função C primária do kernel, start_kernel() (em init/main.c), inicia sua execução, ela copia essa string para estruturas internas do kernel. Essa string imutável é posteriormente exposta ao espaço do usuário através do pseudo-arquivo /proc/cmdline.
2. A Arquitetura de Parsing de Dupla Passagem
A inicialização do kernel apresenta um paradoxo: para alocar memória, o kernel precisa saber se o usuário passou limites de memória (mem=512M), mas para fazer o parse de strings complexas, ele precisa alocar memória. Para resolver isso, o parsing da linha de comando é feito em duas passagens estritas.
Passagem 1: Parâmetros Iniciais (early_param)
Antes do gerenciador de memória Buddy Allocator ou mesmo do console estarem ativos, a função parse_early_param() é chamada.
No código-fonte, certos parâmetros vitais são registrados usando a macro C early_param("nome", funcao_handler). Esses parâmetros configuram a fundação do hardware. Exemplos incluem:
mem=: Restringe artificialmente a quantidade de RAM vista pelo kernel.numa=: Controla a topologia de memória não-uniforme.earlycon: Inicializa uma UART primitiva (console serial) diretamente via portas de I/O, antes do subsistema TTY completo ser carregado, vital para depurar falhas que ocorrem nos primeiros milissegundos de vida do kernel.
Passagem 2: Parâmetros Padrões (__setup e core_param)
Após a memória e a arquitetura básica (CPU, interrupções) estarem inicializadas, o kernel invoca parse_args() para iterar sobre o restante da string.
Subsistemas registram handlers usando a macro __setup("parametro=", funcao). Se o kernel encontrar uma string correspondente, ele chama o ponteiro de função associado, passando o resto da string como argumento. Se uma opção da linha de comando contiver um ponto (module.param), ela é delegada para ser passada ao módulo específico quando (e se) ele for carregado dinamicamente mais tarde.
3. Ancoragem do VFS: Parâmetros de Raiz (root, ro, rw)
O propósito fundamental do kernel é orquestrar recursos, mas ele não tem utilidade sem montar o sistema de arquivos raiz (/). A injeção dessa localização ocorre através da diretiva root=.
root=: Especifica o nó do dispositivo primário. Devido à não-determinação da enumeração assíncrona de barramentos (um disco SCSI pode ser sda ou sdb dependendo de qual controladora responder primeiro na inicialização), usarroot=/dev/sda1é considerado uma falha de engenharia arquitetural moderna. O kernel, através da funçãoname_to_dev_t(), e auxiliado peloinitramfs, aceita UUIDs e PARTUUIDs (root=UUID=1234-abcd).ro(Read-Only) erw(Read-Write): O kernel inicializa o VFS (Virtual File System) montando a raiz especificada em modo restrito. Passarroé o padrão da indústria. Ele obriga o kernel a montar a raiz física inicial sem permissões de escrita, garantindo que as ferramentas de espaço de usuário doinitramfs(como ofsck) possam escanear os superblocos em busca de inconsistências sem risco de concorrência ou corrupção de journal. O sistema de init real (systemd) se encarrega de remontar o VFS comorwposteriormente no ciclo de vida de boot.- **
rootfstype=erootflags=**: Informam preventivamente ao handler de montagem qual driver usar (ex:ext4,xfs) e diretivas específicas do módulo (ex:rootflags=subvol=@para BTRFS), economizando ciclos de CPU que seriam gastos em probing heurístico (adivinhação do sistema de arquivos através de assinaturas de superbloco).
4. O Subsistema de Telemetria e Multiplexação TTY (console=)
O parâmetro console= instrui o subsistema de log do kernel (gerenciado primariamente pela infraestrutura do printk) sobre para onde deve enviar as saídas (outputs) vitais e, bidirecionalmente, de onde aceitar a entrada (stdin em Ring 0). Este é um parâmetro especial porque pode ser declarado múltiplas vezes, multiplexando a saída de emergência.
console=tty0: Direciona o console para o Terminal Virtual (VT) atual do monitor de vídeo local via framebuffer ou driver de vídeo legível.console=ttyS0,115200n8: Direciona os logs para a primeira porta serial UART a uma taxa de 115200 bauds, com 8 bits de dados, sem paridade.
Se um administrador declarar console=tty1 console=ttyS0,115200, o kernel fará o broadcast de seus logs internos (panic, oops, mensagens de boot) tanto para o monitor ligado ao servidor quanto para a conexão de cabo serial no datacenter. Arquiteturalmente, o sistema operacional entregará o /dev/console (e, subsequentemente, o PID 1 e os prompts de login de recuperação) para a última declaração de console encontrada na linha de comando.
5. Controle de Verbosidade: quiet, splash, debug e loglevel
O kernel Linux possui um sistema de limiares (thresholds) para a emissão de mensagens. Cada linha gerada pelo código do kernel (usando a função C printk) é prefixada com um nível de log, variando de 0 (emergência/pânico) a 7 (debug). O comportamento destes logs é modulado por flags na cmdline.
loglevel=N: Um parâmetro numérico (ex:loglevel=3) que manipula diretamente a variável interna de limiar do kernel (console_loglevel). Qualquer mensagem com prioridade mais alta (número menor) que N será enviada ao console.quiet: Este parâmetro é um mero apelido (alias) arquitetural. Quando passado, ele simplesmente força a execução deconsole_loglevel = CONSOLE_LOGLEVEL_QUIET(tipicamente o nível 4). Isso silencia as mensagens informacionais triviais (descobertas de USB ACPI de baixo nível), mas falhas severas ainda irão perfurar o bloqueio.debug: O antônimo dequiet. Ele define oconsole_loglevel = 10, habilitando até mesmo as mensagens de depuração microscópica, resultando em uma avalanche de logs na tela. Utilizado quase exclusivamente para engenharia reversa de falhas de drivers.splash: Ao contrário do senso comum, o parâmetrosplashé solenemente ignorado pelo kernel em Ring 0. Não há função no código-fonte do kernel mapeada para ele via__setup. Ele é lido do/proc/cmdlinepor daemons de espaço de usuário (como o Plymouth) para desenhar telas gráficas e ocultar o texto durante o processo de inicialização.
6. Delegação de Controle: O Parâmetro init=
A responsabilidade primária final da função start_kernel() e de suas threads filhas (kernel_init) é invocar o primeiro processo em espaço de usuário (PID 1). Por padrão estrutural, o kernel tenta executar arquivos em uma ordem codificada fisicamente: /sbin/init, /etc/init, /bin/init, /bin/sh.
A passagem do parâmetro init= sobrescreve totalmente esta heurística de array, instruindo o kernel a usar um binário explícito através de uma transição sys_execve.
init=/lib/systemd/systemd: Padrão adotado em distribuições modernas, forçando o uso do systemd independentemente de links simbólicos em/sbin.init=/bin/bash: A técnica definitiva de invasão e recuperação física (Single-User Mode Override). Ao passar isso, o kernel monta a raiz, mas não inicia o sistema de init. Ele despeja um shell bash com privilégios de root completos. Como nenhum daemon foi carregado, a máquina não tem rede, os daemons não operam e não há syslog, configurando uma ponte de depuração forense inestimável.
7. Segurança, Mitigações e O "Lockdown Mode"
Devido ao poder absoluto garantido pela linha de comando, a integridade desta string é o foco central de modelos de ameaça e segurança física.
- Parâmetros de Mitigação (
mitigations=,spectre_v2=): Permitem que o administrador habilite ou desabilite correções de hardware para falhas de execução especulativa da CPU em tempo real, ponderando entre segurança absoluta e maximização de I/O. - **Ameaça do
init=/bin/sh**: Qualquer pessoa com acesso físico ao teclado durante a tela do GRUB pode apertare, injetarinit=/bin/sh, e comprometer todo o sistema de arquivos (contornando travas PAM, passwords do/etc/shadowe autenticações LDAP). - Integração com Secure Boot e Kernel Lockdown: Em ecossistemas empresariais modernos, se a flag EFI UEFI Secure Boot estiver ativa, o kernel Linux automaticamente transita para o modo "Lockdown" (mesmo se não explicitly solicitado). Nesse estado, o kernel proíbe estritamente o bootloader de modificar a cmdline de maneira que burle a restrição (como desabilitar validações de assinaturas ou forçar
init=/bin/sh). Para evitar isso em topologias extremas, as distribuições usam o UKI (Unified Kernel Image), onde o binário do kernel, o initramfs e a cmdline ASCII são compilados juntos em um único arquivo.efie assinados criptograficamente de forma unitária, impedindo que a linha de comando seja manipulada independentemente sob nenhuma circunstância.