O kernel do Linux não está encontrando o initrd corretamente

9

Eu tinha compilado um kernel Linux e queria depurá-lo no QEMU. Eu criei um arquivo para inicializar fazendo os comandos

$ qemu-img create -f raw disk.img 200M
$ mkfs.ext2 -F disk.img
# mkdir /mnt/rootfs
# mount -o loop disk.img /mnt/rootfs

Então eu fiz qemu -kernel bzImage -initrd disk.img e peguei a tela abaixo que diz:

Kernel panic - not syncing: VFS: unable to mount root fs on unknown block

O que eu fiz de errado e o que posso fazer para corrigir isso?

    
por Coder404 10.03.2013 / 10:11

3 respostas

8

O kernel está lhe dizendo que ele não sabe qual dispositivo contém o sistema de arquivos raiz. Sua montagem de loop não é necessária. (Desmonte-o antes de continuar).

Tente um comando como

qemu -kernel bzImage -hda disk.img -append root=/dev/sda

O parâmetro -hda disk.img diz ao qemu para simular um dispositivo de disco com base no seu disk.img .

A opção -append root=/dev/sda é usada pelo qemu para informar ao kernel sobre seu dispositivo root. Isso é feito anexando o root=/dev/sda à linha de comando do kernel. Você pode comparar isso com a linha de comando do kernel do seu próprio kernel fazendo cat /proc/cmdline (isso é seguro). Você também deve ver um parâmetro root .

    
por 10.03.2013 / 21:33
5

O que está acontecendo é que você está tentando inicializar o Linux da maneira "Obsoleta". É aí que o initrd é um ramdisk ao contrário de um arquivo compactado do cpio descompactado pelo kernel em um ramfs, e com a maneira antiga de mudar para o dispositivo final.

Nesse modo, o kernel monta o disk.img como um ramdisk como o sistema de arquivos raiz e então executa /linuxrc nele. Muito provavelmente no seu caso, não existe tal arquivo. Quando /linuxrc (que deveria fazer o que for necessário para ativar o dispositivo de bloco para o sistema de arquivos raiz real) é encerrado, o kernel monta o sistema de arquivos raiz real.

As mensagens acima mostram que ele monta o disco de RAM com sucesso (1,0: 1 é para ram , então /dev/ram0 ) mas não o sistema de arquivos raiz real / dev / sda1 (8,1: 8 é sd , 1 é a1 ). Presumivelmente, uma vez que você não especificou uma linha de comando do kernel ( -append ), esse /dev/sda1 vem de um CONFIG_CMDLINE passado no tempo de compilação do kernel ou usando rdev .

Se o seu disk.img estiver destinado a conter um sistema de arquivos raiz, digamos, uma pequena distribuição Linux com /sbin/init ..., você provavelmente desejará escrevê-lo:

kvm -kernel kernel.img -initrd disk.img -append 'root=/dev/ram0'

Em seguida, o kernel trataria o disco da RAM como o sistema de arquivos raiz real (embora você ainda possa usar pivot_root para outro).

Para poder ver as mensagens do kernel com mais facilidade, recomendo usar a saída serial:

kvm -kernel kernel.img -initrd disk.img -nographic -append "root=/dev/ram0 console=ttyS0"

Como alternativa, você poderia usar um init ramfs em vez de um disco de inicialização:

mkdir -p RAMFS/{bin,dev} 
cd RAMFS/bin
cp /bin/busybox .
"$PWD/busybox" --install .
cd ..
cp -a /dev/{null,tty,zero,console} dev
printf '%s\n' "#! /bin/sh" "exec /bin/sh" > init
chmod +x init
find . | cpio -oHnewc | gzip > ../initramfs.gz
cd ..
kvm -kernel kernel.img -initrd initramfs.gz

(desde que busybox seja a versão estaticamente vinculada) e você terá um shell e outros utilitários do busybox nesse kernel).

Observe que o kernel agora executa /init em oposição a /linuxrc ou /sbin/init nesse modo.

    
por 10.03.2013 / 23:51
0

CONFIG_BLK_DEV_INITRD=y

Esta opção de configuração do kernel também é necessária. Ele permite o suporte a initrd no kernel do Linux.

Por sorte, o Buildroot o define por padrão para nós quando BR2_TARGET_ROOTFS_CPIO=y é dado.

Você passa o CPIO para o QEMU com a opção qemu -initrd . Meu comando completo do QEMU é:

./buildroot/output.x86_64~/host/usr/bin/qemu-system-x86_64 -m 128M -monitor telnet::45454,server,nowait -netdev user,hostfwd=tcp::45455-:45455,id=net0 -smp 1  -M pc -append ' nopat nokaslr norandmaps printk.devkmsg=on printk.time=y console=ttyS0' -device edu -device lkmc_pci_min -device virtio-net-pci,netdev=net0 -kernel ./buildroot/output.x86_64~/images/bzImage  -nographic  -initrd './buildroot/output.x86_64~/images/rootfs.cpio'

Aqui está um exemplo de Buildered + QEMU totalmente automatizado e minimalista: link

    
por 16.02.2018 / 00:29