Qemu - Emular o próprio sistema para testar os módulos do kernel

0

Atualmente estou iniciando a programação do kernel, implementando um driver de dispositivo de bloco. Consegui fazer uma implementação "simples" e gostaria de aprofundar o que o subsistema de bloco oferece.

Para fazer isso, eu gostaria de emular meu próprio sistema operacional usando o qemu para evitar travar meu sistema operacional de desenvolvimento sempre que cometer um erro no código do dispositivo do kernel.

Configuração do sistema host

Na minha estação de trabalho, estou usando o Debian 9 rodando com o kernel 4.9.0.

$ uname -a
Linux PC325 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux

Criação de disco de imagem

Para criar a máquina virtual, criei uma imagem bruta de 500 M com dd if=/dev/zero of=vm-image.raw bs=1M count=512

E, em seguida, formate-o para ext4 usando mkfs.ext4 vm-image.raw

UPDATE after @meuh comment:
Em seguida, preenchi a imagem do disco da seguinte forma:

mount vm-image.raw /mnt
mkdir /mnt/dev /mnt/lib /mnt/proc /mnt/root /mnt/run /mnt/sbin /mnt/sys
cp -r /etc /mnt/
cp -r /lib/systemd /mnt/lib
ln -s /lib/systemd/systemd /mnt/sbin/init

Agora estou tentando inicializar o sistema operacional emulado, mas estou com problemas para configurá-lo.

Executar comando

$ qemu-system-x86_64 -k fr -kernel /boot/vmlinuz-$(uname -r) -initrd /boot/initrd.img-$(uname -r) -hda vm/vm-image.raw -append "initrd=/boot/initrd.img-$(uname -r) root=/dev/sda rw console=ttyS0" -nographic

Rastreio de inicialização

[...] Kernel boot sequence [...]

Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ... done.
Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... [    2.015241] tsc: Refined TSC clocksource calibration: 3392.292 MHz
[    2.016768] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x30e5dd94d34, max_idle_ns: 440795304975 ns
[    2.895630] random: fast init done
Begin: Waiting for suspend/resume device ... Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
[   11.111765] random: crng init done
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
done.
Gave up waiting for suspend/resume device
done.
Begin: Will now check root file system ... fsck from util-linux 2.29.2
[/sbin/fsck.ext4 (1) -- /dev/sda] fsck.ext4 -a -C0 /dev/sda 
/dev/sda: clean, 3607/32768 files, 12617/131072 blocks
done.
[   35.528453] EXT4-fs (sda): mounted filesystem with ordered data mode. Opts: (null)
done.
Begin: Running /scripts/local-bottom ... done.
Begin: Running /scripts/init-bottom ... done.
run-init: /sbin/init: No such file or directory
[   35.569247] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[   35.569247] 
[   35.570469] CPU: 0 PID: 1 Comm: run-init Not tainted 4.9.0-6-amd64 #1 Debian 4.9.82-1+deb9u3
[   35.571599] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[   35.572695]  0000000000000000 ffffffff9792e074 ffff974c05e14d00 ffffa66e8003feb8
[   35.573741]  ffffffff9777cfbd ffff974c00000010 ffffa66e8003fec8 ffffa66e8003fe60
[   35.574780]  a4112d94e56af84a ffff974c05e14d80 0000000000000100 ffff974c05e84490
[   35.575793] Call Trace:
[   35.576132]  [<ffffffff9792e074>] ? dump_stack+0x5c/0x78
[   35.576815]  [<ffffffff9777cfbd>] ? panic+0xe4/0x23f
[   35.577453]  [<ffffffff9767c2de>] ? do_exit+0xade/0xae0
[   35.578136]  [<ffffffff978058b4>] ? vfs_write+0x144/0x190
[   35.578830]  [<ffffffff9767c313>] ? SyS_exit+0x13/0x20
[   35.579510]  [<ffffffff97603b7f>] ? do_syscall_64+0x8f/0xf0
[   35.580223]  [<ffffffff97c113b8>] ? entry_SYSCALL_64_after_swapgs+0x42/0xb0
[   35.581209] Kernel Offset: 0x16600000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[   35.582584] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[   35.582584] 

Problemas

1 - Tentando ler o dispositivo de disquete

Na inicialização, parece que o kernel tenta ler de um dispositivo de disquete que não existe ou não é legível. O kernel desistiu depois de 30 tentativas, então não é um problema crítico, mas está diminuindo a sequência de inicialização em 30 segundos.

Eu tentei executar o qemu com a opção -no-fd-bootchk , mas isso não mudou nada

ATUALIZAÇÃO:
Precisar -fda floppy.img com floppy.img sendo uma imagem zerada bruta de 1ko suprime as mensagens de erro relacionadas ao disquete e economiza até 20 segundos na inicialização. No entanto, como você pode ver no rastreamento de inicialização, /scripts/local-block ainda está sendo executado várias vezes e leva até 10 segundos antes de passar para a próxima etapa.

2 - Não é possível inicializar o sistema

UPDATE após @meuh comentar:

Parece que o kernel não consegue encontrar um script de inicialização valib. No entanto /sbin/init está presente na imagem do disco e é um link simbólico para /lib/systemd/systemd .

Estou passando por um pânico no kernel, mas não sei o que está causando isso.

Pergunta

Sou muito novo no qemu e acho que não estou tão longe de ter meu sistema emulado funcionando, mas não posso ir mais longe.

Eu tentei brincar com parâmetros, mas não consigo encontrar uma solução para poder inicializar totalmente e ter um prompt do bash em vez do initramdisk one.

ATUALIZADO após @meuh comentar:
O que devo copiar para imagem de disco para poder iniciar o sistema?

    
por Arkaik 16.04.2018 / 15:44

1 resposta

1

Eu não fiz isso, já que normalmente é necessário instalar o qemu a partir de uma iso ou de uma imagem existente do qemu, então provavelmente existe uma maneira mais fácil que a seguinte. O que você está perdendo é praticamente equivalente ao sistema de arquivos que você precisaria para um chroot .

Uma coisa é tentar

sudo debootstrap --arch=amd64 unstable ~/debian-tree/

que desce e descompacta cerca de 300Mbytes de arquivos que você pode "inicializar" como um container systemd e testar com

sudo systemd-nspawn -D ~/debian-tree/ -b

Veja man machinectl . Você pode montar sua imagem do qemu tornando-a um dispositivo de bloco:

sudo apt-get install qemu-utils
sudo modprobe nbd
ls /dev/nbd*   # gives /dev/nbd0  /dev/nbd1 ...
sudo qemu-nbd -c /dev/nbd0 /my/vm-image
sudo mount /dev/nbd0 /mnt/...  # nbd0p1 if you have partitioned
sudo rsync -HSaxX ~/debian-tree/ /mnt/... 

e copie esta árvore para ela. Ao executar o qemu, você normalmente precisa fornecer um tamanho de VM maior para evitar travamentos:

qemu-system-x86_64 -m 512M ... -machine pc,accel=kvm  -cpu host -enable-kvm

Usar -boot d pode evitar o acesso ao disquete.

    
por 16.04.2018 / 19:50