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?