Ok, aqui está a maneira como o processo de inicialização funciona:
- firmware > bootloader talvez > kernel
${parameters}
> initramfs > userspace talvez
Em um disco de instalação do redhat, o sistema de scripts dracut é o que constrói e constitui o initramfs e seu sistema de instalação anaconda constitui o espaço do usuário final.
É udev
que lida com a configuração do dispositivo - como em, ele nomeia os dispositivos em /dev
. Mas isso quase sempre acontece duas vezes - uma vez no initramfs e novamente quando o init
dentro encontrou seu dispositivo raiz de destino e está pronto para montar um devfs
nele.
Então é assim que funciona:
-
O carregador de inicialização (ou firmware) invoca o kernel com um conjunto de parâmetros opcional e uma imagem initramfs opcional. Este conjunto de parâmetros é salvo em
/proc/cmdline
e o kernel ignora todos os parâmetros que não entende. -
O initramfs é um espaço de usuário do linux em funcionamento. Se seu conteúdo
/
é descompactado de uma imagem entregue na invocação ou se eles são compilados não importa - desde o kernel 2.6, ele é sempre o primeiro sistema de arquivos raiz que o kernel do Linux monta. A partir deste ponto, o kernel do Linux deixa tudo para o espaço do usuário.-
Normalmente (como é verdade para o dracut do redhat) o initramfs contém apenas o que é absolutamente necessário para encontrar um dispositivo raiz e montá-lo sobre si mesmo. Geralmente tudo o que está incluído é
busybox
e os módulos do kernel necessários para montar seu dispositivo raiz de destino. -
Provavelmente precisa de
udev
para fazer isso, por issoudev
é mais frequentemente incluído - com o seu próprio pequeno conjunto de regras. -
Como mencionado, o initramfs é seu próprio sistema de arquivos raiz de linux completo. Um completo pode parecer com:
/bin /etc /dev /new_root /proc /sys init
. Geralmente não há nada muito incomum sobre qualquer conteúdo desses diretórios - quase sempre há um/bin/sh
e um/etc/fstab
. -
A maioria dos
init
s irá analisar/proc/cmdline
para quaisquer parâmetros de kernel que eles possam interpretar. Um muito comum éroot=/dev/somedisk
ouroot=UUID=somediskUUID
ouroot=LABEL=somedisklabel
. É o initramfsinit
que interpreta esses parâmetrosroot=...
- não o kernel ou o% finalinit
executado depois (embora o último possa muito bem interpretar outros) . Ele aceitará esse parâmetro e o montará em/new_root
(ou qualquer outro nome usado para a montagem de preparação antes deswitchroot
s) . Seudev
for incluído no initramfs, então é o conjunto de regras initramfs que decide a que a entrada/dev/...
do disco de destino é nomeada agora, mas isso pode mudar. -
Quando o initramfs
init
localiza e monta com êxito o dispositivo/new_root
, ele geralmente procura algo em que oexec
está - geralmente/new_root/bin/init
- então, qualquer que seja o programa, ele se torna pid1. isso com o programaswitch_root
fornecido combusybox
- que faz umexec
enquanto monta simultaneamente/new_root
sobre/
. Seu processo é descrito nos documentos do kernel, assim :
But initramfs is rootfs: you can neither
pivot_root
rootfs, norumount
it. Instead delete everything out of rootfs to free up the space (find -xdev / -exec rm '{}' ';'
), overmount rootfs with the new root (cd /newmount; mount --move . /; chroot .
), attachstdin/stdout/stderr
to the new/dev/console
, andexec
the newinit
. -
-
O dispositivo root
init
apenas executado agora precisa preencher seu próprio sistema de arquivos raiz. Ele chama seuudev
e monta seu própriodevfs
on/dev
com base em seu próprio conjunto de regras e faz todo o resto. Quando estiver pronto, você estará pronto para usar seu computador.
Desculpe pelo nível de detalhes, mas eu queria deixar claro o seguinte:
- qualquer parâmetro do kernel que você entregar do bootloader como
root=/dev/sda
não tem para ser o mesmo/dev/sda
que você eventualmente acessará em/dev/sda
depois que o initramfs/init
for através.
Então, uma maneira de fazer isso, eu acho, é definir uma regra udev
em seu disco anaconda - que é na verdade um arquivo squashfs, provavelmente - que instrui para configurar todos os discos usb Em outro lugar. Há um excelente exemplo aqui:
KERNEL=="sd*", SUBSYSTEMS=="scsi", ATTRS{model}=="USB 2.0 Storage Device", SYMLINK+="usbhd%n"
E seria uma coisa muito boa se você ler o restante desse link também. Você deve ser capaz de fazer isso para que seu dispositivo de disco usb seja /dev/sda
para initramfs - para que você não precise alterar configurações de carregador de inicialização - mas depois cria um nó para o mesmo disco que /dev/usba
para o sistema de instalação anaconda .