Iniciativa mínima CPIO Olá mundo programa passo-a-passo
Compileummundohellosemnenhumadependênciaquetermineemumloopinfinito.init.S
:
.global_start_start:mov$1,%raxmov$1,%rdimov$message,%rsimov$message_len,%rdxsyscalljmp.message:.ascii"FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
Não podemos usar sys_exit
, senão o kernel entra em pane.
Então:
mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
Isso cria um sistema de arquivos com o nosso hello world em /init
, que é o primeiro programa de userland que o kernel executará. Poderíamos também ter adicionado mais arquivos a d/
e eles seriam acessíveis a partir do programa /init
quando o kernel fosse executado.
Então cd
na árvore do kernel Linux, a compilação é como sempre, e execute no QEMU:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
E você deve ver uma linha:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
na tela do emulador! Note que não é a última linha, então você tem que olhar um pouco mais para cima.
Você também pode usar programas em C se os vincular estaticamente:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
com:
gcc -static init.c -o init
Você pode executar em hardware real com um USB em /dev/sdX
e:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Grande fonte sobre este assunto: link Também explica como usar gen_initramfs_list.sh
, que é um script da árvore de código-fonte do kernel do Linux para ajudar a automatizar o processo.
Próxima etapa: configure o BusyBox para que você possa interagir com o sistema: link
Testado no Ubuntu 16.10, QEMU 2.6.1.