Linux Modifica / Adiciona a Linha de Comando do Kernel do InitramFS “UserSpace”

2

Estou desenvolvendo um dispositivo Linux embarcado. Eu criei com sucesso um arquivo de CPIO do InitramFS que é executado rapidamente após a inicialização. Agora, quero alterar a linha de comando inicial do kernel para incluir o parâmetro "quiet" para que eu possa inicializar ainda mais rápido.

No entanto, uma vez que a tela inicial é exibida no InitramFS, eu quero remover a opção silenciosa do kernel para que o restante da inicialização NÃO seja silencioso.

Como posso conseguir isso? Como posso reverter a opção inicial de linha de comando do kernel "silenciosa" assim que eu chegar ao InitramFS?

Obrigado.

    
por PhilBot 09.08.2018 / 14:59

1 resposta

2

Você não pode realmente mudar a linha de comando do kernel após o boot, mas o que você pode fazer é reproduzir os efeitos de configurar ou desarmar a linha de comando quiet através de outros meios, que devem realize o que você deseja alcançar aqui.

Em suma, para aumentar a verbosidade uma vez que você não quer mais quiet , você pode usar este comando:

# echo 7 >/proc/sys/kernel/printk

E para emular o que o quiet faz, é isso que você pode usar:

# echo 4 >/proc/sys/kernel/printk

Isso deve cuidar do lado do kernel da configuração ... Mas às vezes o userspace também altera o comportamento com base nessa opção do kernel. Por exemplo, o systemd analisará a opção quiet na linha de comando do kernel e agirá como se ShowStatus=auto fosse usado em /etc/systemd/system.conf . Se você quiser reverter isso (para forçar o padrão e ignorar a opção quiet ), edite esse arquivo de configuração e descomente a linha ShowStatus=yes lá, que deve cuidar disso.

Pode haver outros sistemas no userspace que olham para esta opção, então você pode precisar dar uma olhada mais de perto para ver como eles se comportam e como reproduzir (ou desfazer) o comportamento da opção estar presente no kernel linha de comando.

O seguinte é um mergulho profundo nas fontes para explicar o comportamento da opção quiet no kernel e no systemd.

O kernel analisa a opção quiet chamando o quiet_kernel() função de inicialização , que faz:

static int __init quiet_kernel(char *str)
{
    console_loglevel = CONSOLE_LOGLEVEL_QUIET;
    return 0;
}

early_param("quiet", quiet_kernel);

A pseudo-variável console_loglevel é, na verdade, a primeiro elemento da matriz console_printk :

extern int console_printk[];

#define console_loglevel (console_printk[0])

Nível de registro " quiet "é definido como 4 :

#define CONSOLE_LOGLEVEL_QUIET   4 /* Shhh ..., when booted with "quiet" */

Algumas linhas abaixo, o o nível de log padrão é definido através de uma configuração do kernel:

/*
 * Default used to be hard-coded at 7, we're now allowing it to be set from
 * kernel config.
 */
#define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT

E essa configuração do kernel é definido no Kconfig.debug, ainda é padronizado como 7 :

config CONSOLE_LOGLEVEL_DEFAULT
    int "Default console loglevel (1-15)"
    range 1 15
    default "7"

(Você pode querer verificar se o seu kernel está usando a configuração padrão, seja em /boot/config-* ou em /proc/config.gz .)

E para mais detalhes sobre o uso de /proc/sys/printk , veja o documentação do kernel para ele . Mas, em suma, é possível escrever apenas um único número, caso em que apenas o primeiro elemento da matriz será atualizado, o que você deseja aqui.

O systemd também irá analisar a linha de comando do kernel, procurando por entradas normalmente nomeadas como systemd.* , mas systemd também reconhece a linha de comando do kernel quiet e a usa para definir o ShowStatus:

    } else if (streq(key, "quiet") && !value) {

            if (arg_show_status == _SHOW_STATUS_UNSET)
                    arg_show_status = SHOW_STATUS_AUTO;

Nesse caso, ele só será definido se não tiver sido definido anteriormente ( _SHOW_STATUS_UNSET ) e será definido como "auto" ( SHOW_STATUS_AUTO .)

Outra maneira de definir o ShowStatus é através do arquivo de configuração :

            { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },

Esta linha descreve a opção de configuração denominada ShowStatus= na seção [Manager] de system.conf . O analisador para esta opção recebe a string "auto" (caso em que o define como SHOW_STATUS_AUTO ) ou usa um booleano, que pode ser "yes", "true" ou "1" para ativá-lo, ou "no", "false" ou "0" para desativá-lo .

A documentação do systemd para --show-status= também é bonita útil aqui. Ele também cita a configuração ShowStatus= (já que passar os argumentos de linha de comando do systemd diretamente nem sempre é fácil de fazer, atualizar um arquivo de configuração é definitivamente uma maneira mais direta de configurar essa configuração).

Espero que você ache isso útil e que ajude você a obter a verbosidade correta para seu caso de uso específico!

    
por 14.08.2018 / 10:25