Como passar argumentos para um kernel Linux 'init =' bootparam?

2

Atualização:

Consegui criar uma demonstração muito simples de usar o init= bootparam para especificar que um binário personalizado ( escrito em golang e compilado) deve ser usado no lugar do init padrão. O binário nesse projeto é compilado para o processador ARM do Raspberry Pi, mas a fonte deve ser compilada para qualquer plataforma.

Publicação original:

Eu coloquei com sucesso o init=/bin/bash no meu bootparams e obtive uma raiz shell na inicialização. Agora eu gostaria de usar o bootparams para executar um script de configuração de "primeira inicialização".

NOTA:

Eu sei que existem muitas alternativas que podem ser oferecidas. Deixe esses como comentários sobre a questão, se quiser. Mas eu não posso usá-los; esta questão não é sobre eles; eles não são respostas para essa pergunta. Então, por favor, não publique alternativas como respostas . * Não é útil para as pessoas que vieram aqui para esta questão.

As coisas que eu tentei falharam:

  • init="/bin/bash -c 'mount /dev/mmcblk0p1 /boot; date > /boot/test.txt'"
  • init='/bin/bash -c "mount /dev/mmcblk0p1 /boot; date > /boot/test.txt"'
  • init="/bin/bash"
  • init='/bin/bash'

Então, vou supor que até mesmo citar seu init= param não é uma opção.

  1. Corrija-me se estiver errado aqui.

Eu li a documentação do Linux Kernel sobre o assunto. Diz:

The kernel parses parameters from the kernel command line up to --; if it doesn’t recognize a parameter and it doesn’t contain a ., the parameter gets passed to init: parameters with = go into init’s environment, others are passed as command line arguments to init. Everything after -- is passed as an argument to init.

...

init=    [KNL]
         Format: <full_path>
         Run specified binary instead of /sbin/init as init
         process.
  • Lição aprendida:

    Esse Format: <full_path> explicaria por que ele não gosta de colocar um comando completo (ou vários) no init=

    Eu também li BOOTPARAM (7) (procure por "passado para o processo de inicialização ") onde eles dizem:

    Anything of the form 'foo=bar' that is not accepted as a setup function as described above is then interpreted as an environment variable to be set. A (useless?) example would be to use 'TERM=vt100' as a boot argument.

    Any remaining arguments that were not picked up by the kernel and were not interpreted as environment variables are then passed onto PID 1, which is usually the init(1) program. The most common argument that is passed to the init process is the word 'single' which instructs it to boot the computer in single user mode, and not launch all the usual daemons. Check the manual page for the version of init(1) installed on your system to see what arguments it accepts.

    1. Existem exemplos de uso dessa informação para passar argumentos a um init= ?
    2. personalizado especificado?

    Se houver, é difícil encontrar e essa pergunta será exibida nos resultados do Google. Se não houver, criaremos um exemplo de trabalho para a comunidade.

        
  • por Bruno Bronosky 05.03.2018 / 19:53

    1 resposta

    4

    Sim, é assim que você tradicionalmente diz ao sistema init regular em que estado inicializar. Se você está rodando o sysv-init (ou praticamente qualquer sistema init amplamente utilizado além do systemd), você pode colocar um número entre 1 e 5 no final dos argumentos do kernel e ele irá inicializar nesse nível (1 é sempre modo de usuário único, os outros são definidos pelo sistema, 3 ou 4 é o que a maioria das distribuições Linux usava convencionalmente como padrão). Se você estiver usando o systemd, poderá passar single ou emergency no final dos argumentos do kernel para inicializar nesses modos respectivamente.

    Usar esse mecanismo para passar argumentos arbitrários, porém, é um pouco difícil, porque o kernel faz o mínimo absoluto de análise, o que significa, em particular, que:

    • Argumentos com espaços em branco neles não podem ser passados, porque o kernel não analisa strings entre aspas (isto é, 'some string' é analisado como dois argumentos 'some e string' ).
    • Você não pode referenciar nenhuma variável de ambiente, porque o kernel não faz a substituição de variáveis (o que normalmente é feito pelo shell em que você está executando o comando antes mesmo de iniciar o comando).
    • Em geral, os argumentos devem ser interpretados corretamente sob o código de idioma POSIX C (essencialmente US ASCII), que lança a internacionalização pela janela, a menos que você queira usar algo como base64 ou punycode.
    • Existe um limite máximo de quantos dados podem ser passados nos argumentos do kernel, mas esqueci o que é.

    Essas limitações combinadas são o motivo pelo qual você não consegue encontrar nada no Google sobre esse tipo de coisa, nenhum engenheiro de integração de sistemas faz isso, porque é muito mais difícil contornar as limitações acima do que simplesmente escreva um script contendo todos os argumentos necessários e chame isso.

        
    por 05.03.2018 / 21:13