Programma minimo init hello world passo dopo passo
Compila un hello world senza dipendenze che termina in un ciclo infinito. init.S
:
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $message, %rsi
mov $message_len, %rdx
syscall
jmp .
message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
Non possiamo usare la chiamata di sistema exit, altrimenti il kernel va in panico, l'unico modo per uscire con grazia da init è spegnere la macchina con reboot
chiamata di sistema.
Quindi:
mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o # link
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
Questo crea un filesystem con il nostro hello world in /init
, che è il primo programma userland che verrà eseguito dal kernel. Avremmo anche potuto aggiungere altri file a d/
e sarebbero accessibili dal /init
programma quando il kernel è in esecuzione.
Poi cd
nell'albero del kernel di Linux, compila come al solito ed eseguilo in 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"
Dovresti vedere una riga:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
sullo schermo dell'emulatore! Nota che non è l'ultima riga, quindi devi guardare un po' più in alto.
Puoi anche usare programmi C se li colleghi staticamente:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
con:
gcc -static init.c -o init
Il collegamento dinamico richiederebbe l'impostazione di un eseguibile del linker dinamico, il più comune dei quali fa parte delle librerie standard C come glibc.
Puoi girare su hardware reale con una USB su /dev/sdX
e:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Ottima fonte su questo argomento:Suggerimento tecnico:come utilizzare initramfs | landley.net Spiega anche come usare gen_initramfs_list.sh
, che è uno script dall'albero dei sorgenti del kernel Linux per aiutare ad automatizzare il processo.
Testato su Ubuntu 16.10, QEMU 2.6.1.
Passaggi successivi
La prossima cosa che vuoi fare è configurare BusyBox.
BusyBox implementa le utility CLI POSIX-y di base, inclusa una shell POSIX-y, che ti consente di sperimentare più facilmente il sistema in modo interattivo.
Personalmente, a questo punto preferisco affidarmi solo a Buildroot, che è un fantastico set di script che automatizza la compilazione di tutto dal sorgente e crea il filesystem di root.
Ho caricato un helper altamente dettagliato e automatizzato per questo su:https://github.com/cirosantilli/linux-kernel-module-cheat
Non inizierei a scherzare con LFS, che è un sentiero del giardino che porta a un bosco oscuro.
Inizia con una distribuzione in cui hai molto controllo sull'installazione iniziale, come Arch, o un'edizione senza testa come il server Ubuntu. Il punto non è tanto risparmiare spazio quanto delimitare la complessità della configurazione di init; partendo da una distro headless, se l'applicazione che si desidera eseguire richiede una GUI, è possibile aggiungere ciò che è necessario per questo senza dover finire con un login GUI (ovvero il display manager o DM) avviato da init e un desktop completo ambiente adatto.
Quindi vuoi imparare come configurare il sistema init per i tuoi scopi:nota che non puoi fare a meno di init e potrebbe essere il mezzo migliore per raggiungere il tuo obiettivo. Il sistema init utilizzato sulla maggior parte delle distribuzioni Linux ora è systemd.
Il punto qui è ridurre al minimo ciò che init fa all'avvio, ed è così che puoi creare un sistema che eseguirà una quantità minima di software per supportare l'applicazione su cui vuoi concentrarti:questo è essenzialmente il modo in cui viene configurato un server, A proposito, quindi è un'attività comune (nota che non puoi letteralmente avere "solo" un processo utente in esecuzione, almeno non in modo utile).
Se l'applicazione che vuoi eseguire è un programma GUI (un buon esempio del perché non puoi letteralmente eseguire solo un'applicazione, poiché le app GUI richiedono un server X), puoi avere un ~/.xinitrc
che assomiglia a questo;
#!/bin/sh
myprogram
Quando poi startx
, il tuo programma sarà l'unica cosa in esecuzione e sarà impossibile cambiare desktop o avviare qualsiasi altra cosa, in parte perché non c'è un gestore di finestre o un ambiente desktop (quindi, non ci sarà nemmeno la cornice della finestra o la barra del titolo).
se sei un po' in programmazione e vuoi crearlo da zero puoi andare con LFS cioè Linux da Scratch http://www.linuxfromscratch.org/
se vuoi personalizzare ubutnu puoi usare ubunt-builder e se lo vuoi su base rpm puoi usare SUsE-Studio,Suse studio ti permetterà di creare suse linux personalizzato
evviva