Por que preciso do initramfs?

17

Eu descobri que se eu escolher jffsou sdcomo sistema de arquivos (e não initramfs), o tamanho do kernel será muito pequeno (1,4 MB em comparação com o initramfsqual é 3,4 MB). Isso significa que initramfsocupa um espaço consideravelmente grande. Então, se eu puder, eu o removeria completamente e, portanto, terá um kernel muito pequeno, que é o que eu quero.

A pergunta básica que surge em minha mente é: Por que eu preciso initramfs? Um kernel Linux não pode inicializar sem ter um sistema de arquivos inicial?

Meu aplicativo final fará apenas cálculo e comunicação - sem armazenamento. Portanto, um sistema operacional sem sistema de arquivos faz sentido - pelo menos para a minha aplicação.

gpuguy
fonte
2
Você não pode prescindir do initramfs. É possível ficar sem o arquivo initramfs adicional, mas independentemente do que você faz, o kernel inclui seu próprio vazio ou não. Portanto, não entendo sua pergunta - de que distribuição você está falando? Como você está construindo seu kernel? Você pode fornecer o arquivo .config do kernel? Estes são muito importantes. Eu suspeito que sua distribuição está compilando seus initramfs diretamente no kernel - e, portanto, preenchendo os initramfs vazios que ele contém - mas não posso saber com base nas informações que você forneceu.
mikeserv
2
@mikeserv, obviamente, um initramfs embutido, mas vazio / não utilizado, não conta.
Psusi
Bem, @psusi os documentos do kernel discordam. E sou tão inflexível quanto a isso, porque não precisa haver nenhum mistério - é apenas /root- é isso. A única coisa que faz de maneira diferente é switch_rootque, mesmo que, desde que sejam tomadas as devidas precauções com determinados módulos do kernel carregados, isso possa ser feito a qualquer momento. O Initramfs nada mais é do que uma imagem de disco - cheia ou não, está lá. E você nunca está sem ele - é a sua raiz, afinal. Apenas não deve ser um mistério, é o que penso, e não gosto de toda a confusão desnecessária que o cerca.
mikeserv
2
@mikeserv, no, / root é o diretório inicial do usuário root. O rootfs é /, que então tem a raiz real montada sobre ela. Você está apenas discutindo semântica. Para os fins desta discussão, não ter um initramfs significa não ter um arquivo no disco que seu carregador de inicialização precisa carregar e passar para o kernel.
Psusi 30/03/14
Isso é verdade, eu só usei / root por questões de clareza, mas vou lhe dar uma. Mas não, eles não são semânticos, eles são a mecânica fundamental do seu kernel Linux. Estas são coisas básicas. Vamos apenas tentar acertar.
mikeserv

Respostas:

11

O aumento de tamanho de um initramfs não se deve ao driver ramfs (são apenas alguns kB e é necessário para outras coisas), mas ao próprio initramfs. O initramfs contém programas que são necessários para montar e montar o sistema de arquivos raiz real.

O Initramfs facilita muito e, em alguns casos, é possível (por exemplo, criptografado /) inicializar o sistema. É altamente recomendável mantê-lo em hardware no estilo PC com muitos periféricos hotpluggable. Por outro lado, faz muito sentido inicializar um dispositivo incorporado sem o initramfs, com um kernel que suporta apenas a configuração de hardware específica para a qual foi construído.

Obviamente, o kernel precisa inicializar em um sistema de arquivos: deve haver uma maneira de carregar qualquer aplicativo que você queira executar. Se você não estiver executando nada, mantenha a máquina desligada.

Se você não quiser usar um initramfs, diga ao seu gerenciador de inicialização para não passar um. Também não inclua um na saída da compilação do kernel, é claro - como isso acontece se for dependente da arquitetura e do carregador de inicialização: por exemplo, vmlinuxe bzImagenão inclua o initramfs (eles são o kernel bruto e compactado, respectivamente ), mas uImage(para U-Boot) compacta o kernel e o initramfs, se houver um.

(Tecnicamente, como mikeserv observa, sempre há um initramfs - mas, por padrão, é um arquivo vazio de 134 bytes. O que você está vendo e quer se livrar é um initramfs "verdadeiro" e não vazio criado por seu processo de construção e contendo ferramentas que são usadas para montar o sistema de arquivos raiz.)

Lembre-se de que um initramfs pode ser uma maneira razoável de criar um sistema de aplicativo único sem dados persistentes: coloque todo o seu aplicativo no initramfs, inicialize-o e mantenha-o. Isso facilita a organização do armazenamento persistente ou da imagem de inicialização (tudo o que você precisa é do kernel e do initramfs, que pode ser empacotado). No entanto, há desvantagens nessa abordagem: todos os dados no initramfs serão armazenados permanentemente na RAM e você não pode modificar facilmente os arquivos na imagem de inicialização; é necessário reconstruir o arquivo morto.

Gilles 'SO- parar de ser mau'
fonte
Se você estiver usando um kernel linux 2.6 ou mais recente, terá o initramfs. Se você usa ou não uma imagem secundária do initramfs, como é habitual, é outra questão, mas o initramfs não é opcional.
mikeserv
2
@ MikeServ Você tem um, sim. Mas um initramfs vazio é amendoim. Ele não precisa ser usado (o que requer que ele contenha programas suficientes para montar a raiz real, o que aumenta o tamanho de maneira não negligenciável em um sistema embarcado típico).
Gilles 'SO- stop be evil'
Amendoins obrigatórios de qualquer maneira. E eu não sei quando eu disse o contrário! O solicitante estava solicitando informações sobre como removê-lo como um sistema de arquivos - o que não é possível.
mikeserv
E sim, ele precisa ser usado - sem o initramfs não há raiz. Sempre.
mikeserv
8

Do LFS :

O único objetivo de um initramfs é montar o sistema de arquivos raiz. O initramfs é um conjunto completo de diretórios que você encontraria em um sistema de arquivos raiz normal. Ele é empacotado em um único arquivo cpio e compactado com um dos vários algoritmos de compactação.

...

Existem apenas quatro razões principais para ter um initramfs no ambiente LFS: carregar os rootfs de uma rede, carregá-los de um volume lógico do LVM, ter rootfs criptografados nos quais é necessária uma senha ou a conveniência de especificar os rootfs como LABEL ou UUID. Qualquer outra coisa geralmente significa que o kernel não foi configurado corretamente.

...

Para a maioria das distribuições, os módulos do kernel são a maior razão para ter um initramfs. Em uma distribuição geral, existem muitas incógnitas, como tipos de sistema de arquivos e layouts de disco. De certa forma, é o oposto do LFS, onde os recursos e o layout do sistema são conhecidos e um kernel personalizado é normalmente construído. Nessa situação, um initramfs raramente é necessário.

Outra fonte www.kernel.org

Além disso, existem muitos sistemas Linux que gostam de roteadores que não usam o initramfs.


fonte
1

Você precisa de um initramfs para configurações mais complexas, como inicialização de rede, ou lvm ou raid, pois eles requerem alguns utilitários de modo de usuário para configurar o acesso ao fs raiz. Para uma partição simples e convencional em um disco, desde que você tenha os drivers de disco incorporados ao kernel e especifique o argumento raiz pelo caminho do dispositivo, em vez do UUID, poderá usar o initramfs. Obviamente, o caminho do dispositivo está sujeito a alterações, dependendo de quais dispositivos plug and play (por exemplo, usb) que você conectou, ou mesmo de variações aleatórias aleatórias, e é por isso que praticamente todo mundo usa uuids e initramfs para confiabilidade.

psusi
fonte
Isso também está incorreto.
mikeserv
6
@mikeserv, seu comentário é inútil. Se você pretende reivindicar isso, precisa explicar o porquê.
Psusi
Eu fiz, ou melhor, a documentação do kernel que compõe cerca de 99% da minha resposta.
mikeserv
@mikeserv, está correto. Estou executando o Gentoo linux há anos sem o initramfs.
Tim
1

Esta é uma pergunta antiga, mas ainda não parece ter uma resposta aceita, portanto, eu a divulgarei (não sou especialista aqui, estou tentando descobrir isso sozinha).

Em https://www.kernel.org/doc/Documentation/early-userspace/README (todo o caminho que indica que não foi atualizado desde 2004).

Atualmente, o kernel possui três maneiras de montar o sistema de arquivos raiz:

a) todos os drivers de dispositivo e sistema de arquivos necessários compilados no kernel, sem initrd. init / main.c: init () chamará prepare_namespace () para montar o sistema de arquivos raiz final, com base na opção root = e opcional init = para executar algum outro binário init que não esteja listado no final de init / main.c: init ()

b) alguns drivers de dispositivo e sistema de arquivos criados como módulos e armazenados em um initrd. O initrd deve conter um '/ linuxrc' binário que deve carregar esses módulos de driver. Também é possível montar o sistema de arquivos raiz final via linuxrc e usar o syscall pivot_root. O initrd é montado e executado via prepare_namespace ().

c) usando o initramfs. A chamada para prepare_namespace () deve ser ignorada. Isso significa que um binário deve fazer todo o trabalho. O referido binário pode ser armazenado no initramfs através da modificação de usr / gen_init_cpio.c ou através do novo formato initrd, um arquivo cpio. Deve ser chamado "/ init". Esse binário é responsável por fazer tudo o que prepare_namespace () faria.

Para manter a compatibilidade com versões anteriores, o binário / init só será executado se vier por meio de um arquivo initramfs cpio. Se esse não for o caso, init / main.c: init () executará prepare_namespace () para montar a raiz final e executar um dos binários predefinidos do init.

Pelo que vale, acredito que dispositivos / distros como o Raspberry Pi, etc. não usam o initramfs; em alguns casos, o kernel está na partição raiz (montado pelo gerenciador de inicialização que possui módulos fs necessários). Em outros casos em que o kernel está, por exemplo, em uma /bootpartição, o initramfs na mesma partição pode ser acessado diretamente antes de montar o rootfs como outros. declararam.

Em alguns casos, o initramfs pode ser incorporado no mesmo arquivo que o kernel, mas esse nem sempre é o caso. (a) parece afirmar claramente que, em alguns casos, o initramfs não é necessário.

thom_nic
fonte
0

Acho a explicação a seguir mais clara,

initramfsé um sistema de arquivos raiz que é incorporado ao kernel e carregado no estágio inicial do processo de inicialização. É o sucessor do initrd. Ele fornece um espaço inicial para o usuário que pode fazer coisas que o kernel não pode fazer facilmente sozinho durante o processo de inicialização.

O uso do initramfs é opcional. Por padrão, o kernel inicializa o hardware usando drivers embutidos, monta a partição raiz especificada, carrega o sistema init da distribuição Linux instalada. O sistema init carrega módulos adicionais e inicia os serviços até permitir o logon. Esse é um bom comportamento padrão e suficiente para muitos usuários. O initramfs é para usuários com requisitos avançados; para usuários que precisam fazer as coisas o mais cedo possível, mesmo antes da montagem da partição raiz.

Aqui estão alguns exemplos do que você pode fazer com o initramfs:

  • Monte a partição raiz (para partições criptografadas, lógicas e de outra forma especiais);
  • Forneça um shell de resgate minimalista (se algo der errado);
  • Personalize o processo de inicialização (por exemplo, imprima uma mensagem de boas-vindas, respingo de inicialização etc.);
  • Carregar módulos (por exemplo, drivers de terceiros);
  • Qualquer coisa que o kernel não possa fazer (contanto que você possa fazê-lo no espaço do usuário, por exemplo, executando comandos). Se você não possui requisitos avançados, não precisa do initramfs.
Sufiyan Ghori
fonte
-1

Não importa o que você faça, você tem initramfs. Não há como ficar sem ele - é o único sistema de arquivos imposto a você. Do kernel.org :

O que é rootfs?

Rootfsé uma instância especial de ramfs(ou tmpfs, se estiver ativada), que está sempre presente nos sistemas 2.6. Você não pode desmontarrootfs pelo mesmo motivo que não pode matar o processo de inicialização; em vez de ter um código especial para procurar e manipular uma lista vazia, é menor e mais simples para o kernel garantir que determinadas listas não possam ficar vazias.

A maioria dos sistemas simplesmente monta outro sistema de arquivos rootfse o ignora. A quantidade de espaço que uma instância vazia de ramfs ocupa é pequena.

Se * CONFIG_TMPFS * estiver ativado, rootfsserá usado em tmpfsvez de ramfspor padrão. Para forçar ramfs, adicione "rootfstype=ramfs"à linha de comando do kernel.

O que é o initramfs?

Todos os kernels 2.6 do Linux contêm um arquivo compactado em"cpio"formatogzip, que é extraído rootfsquando o kernel é inicializado. Após a extração, o kernel verifica serootfscontém um arquivoe"init" , se for o caso, executa-o como PID 1. Se encontrado, esseinitprocesso é responsável por elevar o sistema até o fim, incluindo a localização e montagem do dispositivo raiz real ( caso existam). Serootfsnão contiver uminitprograma após acpioextração do arquivoincorporado, o kernel recorrerá ao código mais antigo para localizar e montar uma partição raiz e, em seguida, executar alguma variante/sbin/initdisso.

Tudo isso difere do antigo initrd de várias maneiras:

  • O initrd antigo sempre foi um arquivo separado, enquanto o arquivo initramfs é vinculado à imagem do kernel do linux. (O diretório linux - * / usr é dedicado à geração desse arquivo durante a construção.)

  • O arquivo initrd antigo era uma imagem do sistema de arquivos compactada com gzip (em algum formato de arquivo, como ext2, que precisava de um driver embutido no kernel), enquanto o novo arquivo initramfs é um arquivo cpio compactado com gzip (como tar apenas mais simples, consulte cpio (1) e Documentação / early-userspace / buffer-format.txt). O código de extração cpio do kernel não é apenas extremamente pequeno, também é __init texto e dados que podem ser descartados durante o processo de inicialização.

  • O programa executado pelo antigo initrd (que foi chamado / initrd, não / init) fez algumas configurações e depois retornou ao kernel, enquanto o programa init do initramfs não deve retornar ao kernel. (Se o / init precisar transferir o controle, ele poderá sobrescrever / com um novo dispositivo raiz e executar outro programa init. Consulte o utilitário switch_root, abaixo.)

  • Ao alternar para outro dispositivo raiz, o initrd pivot_root e desmontar o ramdisk. Mas o initramfs é rootfs: você não pode pivot_root rootfs nem desmontá-lo. Em vez disso, exclua tudo do rootfs para liberar espaço (encontre -xdev / -exec rm '{}' ';'), substitua o rootfs pela nova raiz (cd / newmount; mount --move. /; Chroot.), anexe stdin / stdout / stderr ao novo / dev / console e execute o novo init.

Como esse é um processo notavelmente persnickety (e envolve a exclusão de comandos antes que você possa executá-los), o pacote klibc introduziu um programa auxiliar (utils / run_init.c) para fazer tudo isso por você. A maioria dos outros pacotes (como o busybox) nomeou esse comando "switch_root".

Preenchendo initramfs:

O processo de construção do kernel 2.6 sempre cria um arquivo initramfs no formato cpio compactado em gzip e o vincula ao binário do kernel resultante. Por padrão, esse arquivo está vazio (consumindo 134 bytes em x86).

A opção de configuração CONFIG_INITRAMFS_SOURCE (na Configuração Geral em menuconfig e vivendo em usr / Kconfig) pode ser usada para especificar uma fonte para o arquivo initramfs, que será automaticamente incorporado no binário resultante. Esta opção pode apontar para um arquivo cpio gzipped existente, um diretório que contém arquivos a serem arquivados ou uma especificação de arquivo de texto, como o exemplo a seguir:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Execute "usr / gen_init_cpio" (após a compilação do kernel) para obter uma mensagem de uso documentando o formato de arquivo acima.

Uma vantagem do arquivo de configuração é que o acesso raiz não é necessário para definir permissões ou criar nós do dispositivo no novo arquivo morto. (Observe que essas duas entradas de "arquivo" de exemplo esperam encontrar arquivos denominados "init.sh" e "busybox" em um diretório chamado "initramfs", no diretório linux-2.6. *. Consulte Documentation / early-userspace / README para obter mais informações. mais detalhes.)

O kernel não depende de ferramentas externas do cpio. Se você especificar um diretório em vez de um arquivo de configuração, a infraestrutura de compilação do kernel criará um arquivo de configuração a partir desse diretório (usr / Makefile chama scripts / gen_initramfs_list.sh) e passa a empacotar esse diretório usando o arquivo de configuração (alimentando-o para usr / gen_init_cpio, que é criado a partir de usr / gen_init_cpio.c). O código de criação do cpio em tempo de construção do kernel é totalmente independente e o extrator de tempo de inicialização do kernel também é (obviamente) independente.

mikeserv
fonte
1
Você pode inicializar sem um initramfs. Sua resposta expõe os méritos do initramfs, mas isso não se aplica a sistemas embarcados típicos, e mesmo em desktops ou servidores onde um initramfs é recomendado, não é obrigatório.
Gilles 'SO- stop be evil'
@ Gilles - não, você não pode. Independentemente do que você faz, você possui o initramfs. Ele está compilado no kernel - agora, seu kernel, meu kernel, todos os nossos. Leia os documentos do kernel - todo o meu post foi um copiar e colar. Você está incorreto. Como você pode contestar a documentação oficial?
mikeserv
1
Não discuto a documentação oficial, discuto as conclusões que você está tirando dela. Você está lendo a documentação que explica como usar um initramfs. Em nenhum lugar afirma que o initramfs deve ser usado.
Gilles 'SO- stop be evil'
@Gilles Se isso não for bom o suficiente: "O processo de compilação do kernel 2.6 sempre cria um arquivo initramfs no formato cpio com gzip e o vincula ao binário resultante do kernel. Por padrão, esse arquivo está vazio (consumindo 134 bytes no x86) .... " Eu posso fazer melhor. O acima foi uma pesquisa na web de 2 ou 3 minutos.
mikeserv
3
Eu li a documentação. Eu faço isso para viver. Não é uma questão de opinião. Sempre existe um initramfs, mas não é necessariamente usado para inicializar. Não consigo encontrar uma explicação decente da estrutura do kernel para esse caso, provavelmente porque é o caso clássico que não se justifica explicar. A lógica principal está em do_mounts.c- especificamente prepare_namespace, na qual saved_root_nameé preenchida o root=argumento da linha de comando.
Gilles 'SO- stop be evil