Minha pergunta é com relação à inicialização de um sistema Linux a partir de uma partição / inicialização separada. Se a maioria dos arquivos de configuração está localizada em uma partição / separada, como o kernel o monta corretamente no momento da inicialização?
Qualquer elaboração sobre isso seria ótimo. Sinto como se estivesse perdendo algo básico. Estou principalmente preocupado com o processo e a ordem das operações.
Obrigado!
Edição: Eu acho que o que eu precisava perguntar era mais ao longo das linhas do arquivo dev que é usado no parâmetro raiz do kernel. Por exemplo, digamos que eu forneça meu parâmetro raiz como root = / dev / sda2. Como o kernel possui um mapeamento do arquivo / dev / sda2?
Respostas:
Inicialmente, o Linux inicializa com um ramdisk (chamado
initrd
de "INITial RamDisk") como/
. Este disco possui apenas o suficiente para encontrar a partição raiz real (incluindo os módulos de driver e sistema de arquivos necessários). Ele monta a partição raiz em um ponto de montagem temporário no einitrd
, em seguida, chamapivot_root(8)
para trocar os pontos de montagem raiz e temporário, deixando ainitrd
posição em que seráumount
editada e o sistema de arquivos raiz real/
.fonte
Nos tempos antigos, o kernel era codificado para conhecer o número principal / menor do dispositivo, os fs raiz e o montou depois de inicializar todos os drivers de dispositivo que foram incorporados ao kernel. O
rdev
utilitário pode ser usado para modificar o número do dispositivo raiz na imagem do kernel sem precisar recompilar.Eventualmente, os carregadores de inicialização apareceram e poderiam passar uma linha de comando para o kernel. Se o
root=
argumento foi passado, isso informava ao kernel onde estava o root fs, em vez do valor incorporado. Os drivers precisavam acessar o que ainda precisava ser incorporado ao kernel. Embora o argumento pareça um nó de dispositivo normal no/dev
diretório, obviamente não existe um/dev
diretório antes da montagem do root fs, portanto o kernel não pode procurar um nó de desenvolvimento lá. Em vez disso, certos nomes de dispositivos conhecidos são codificados no kernel para que a string possa ser traduzida para o número do dispositivo. Por causa disso, o kernel pode reconhecer coisas como/dev/sda1
, mas não coisas mais exóticas, como/dev/mapper/vg0-root
um UUID de volume.Mais tarde, o
initrd
entrou em cena. Junto com o kernel, o carregador de inicialização carregava ainitrd
imagem, que era algum tipo de imagem do sistema de arquivos compactada (imagem ext2 compactada com gzip, imagem romfs compactada com gzip, squashfs finalmente se tornou dominante). O kernel descompactaria essa imagem em um ramdisk e montaria o ramdisk como o root fs. Esta imagem continha alguns drivers adicionais e scripts de inicialização, em vez de reaisinit
. Esses scripts de inicialização executavam várias tarefas para reconhecer hardware, ativar coisas como matrizes de ataque e LVM, detectar UUIDs e analisar a linha de comando do kernel para encontrar a raiz real, que agora poderia ser especificada por UUID, rótulo de volume e outras coisas avançadas. Em seguida, montou o fs raiz real/initrd
e executou apivot_root
chamada do sistema para trocar o kernel/
e/initrd
, em seguida, exec/sbin/init
na raiz real, que desmontaria/initrd
e liberaria o ramdisk.Finalmente, hoje temos o
initramfs
. Isso é semelhante aoinitrd
, mas em vez de ser uma imagem do sistema de arquivos compactada carregada em um ramdisk, é um arquivo cpio compactado. Um tmpfs é montado como raiz e o arquivo é extraído lá. Em vez de usarpivot_root
, que era considerado um hack sujo, osinitramfs
scripts de inicialização montam a raiz real/root
, excluem todos os arquivos na raiz tmpfs, depoischroot
no/root
e exec/sbin/init
.fonte
Parece que você está perguntando como o kernel "sabe" qual partição é a partição raiz, sem acesso aos arquivos de configuração em / etc.
O kernel pode aceitar argumentos de linha de comando como qualquer outro programa. O GRUB ou a maioria dos outros gerenciadores de inicialização podem aceitar argumentos de linha de comando como entrada do usuário ou armazená-los e disponibilizar várias combinações de argumentos de linha de comando por meio de um menu. O carregador de inicialização passa os argumentos da linha de comando para o kernel quando o carrega (não sei o nome ou a mecânica desta convenção, mas provavelmente é semelhante à maneira como um aplicativo recebe argumentos da linha de comando de um processo de chamada em um kernel em execução).
Uma dessas opções de linha de comando é
root
onde você pode especificar o sistema de arquivos raiz, ou sejaroot=/dev/sda1
.Se o kernel usa um initrd, o gerenciador de inicialização é responsável por informar ao kernel onde está ou colocar o initrd em um local de memória padrão (eu acho) - é pelo menos assim que funciona no meu Guruplug.
É perfeitamente possível não especificar um e, em seguida, deixar o kernel em pânico imediatamente após começar a reclamar que não consegue encontrar um sistema de arquivos raiz.
Pode haver outras maneiras de passar essa opção para o kernel.
fonte
/dev/sda1
porque é uma entrada em um sistema de arquivos. Você poderia fazercp -p /dev/sda1 /tmp/foo
e/tmp/foo
representaria o mesmo dispositivo. Na linha de comando do kernel, o kernel usa um analisador interno que segue a convenção usual de nomenclatura de dispositivos:sda1
significa a primeira partição do primeiro disco do tipo SCSI.initrd
ouinitramfs
quero dizer. Tem que ser uma partição "simples" no/dev/sdx
formulário?init/do_mounts.c
.O Grub monta a
/boot
partição e depois executa o kernel. Na configuração do Grub, ele diz ao kernel o que usar como dispositivo raiz.Por exemplo, no Grub
menu.lst
:fonte
Vamos lá, o GRUB não "monta" / inicializa, apenas lê 'menu.lst' e alguns módulos, também não faz parte do kernel do LINUX. Quando você chama o kernel, passa um argumento "root" com a partição raiz. Na pior das hipóteses, o kernel sabe que just / boot foi montado (LOL).
Próximo: geekosaur está certo, o Linux usa um ramdisk inicial no formato de imagem compactada e monta o sistema de arquivos raiz real chamando
pivot_root
. Portanto, o Linux começa a executar a partir de uma imagem e, em seguida, a partir da sua unidade de disco local.fonte
O gerenciador de inicialização, seja grub ou lilo ou qualquer outra coisa, informa ao kernel onde procurar com a
root=
flag e, opcionalmente, carrega um ramdisk inicial na memóriainitrd
antes de inicializar o kernel.O kernel é carregado, testa seus drivers de hardware e dispositivo e procura no sistema o que pode ver (você pode revisar essas informações de diagnóstico digitando
dmesg
; hoje em dia provavelmente rola muito rápido para ver) e tenta montar a partição mencionada em oroot=
parâmetroSe um initrd estiver presente, ele será montado primeiro e quaisquer módulos / drivers de dispositivo nele serão carregados e testados antes da montagem do sistema de arquivos raiz. Dessa forma, você pode compilar os drivers para seus discos rígidos como módulos e ainda poder inicializar.
fonte