Come creare una distro Linux personalizzata che esegue solo un programma e nient'altro?


12

Come ho potuto creare la mia distro Linux "personalizzata" che eseguirà un solo programma, praticamente esattamente allo stesso modo di XBMCbuntu .


Benvenuto in U&L, per favore fai una visita guidata e prenditi il ​​tempo per imparare a fare una domanda che cosa vuoi fare? perché la definizione di applicazione è piuttosto vaga e non significa affatto nulla, perché il mio consiglio sarebbe di usare busyboxma probabilmente non è quello che vuoi. quindi per favore, prenditi il ​​tempo necessario per esprimere le tue necessità e potremmo essere in grado di aiutarti. Non esitare a modificare la tua domanda per aggiungere qualsiasi elemento rilevante in essa.
Kiwy,

1
Mi sembra abbastanza chiaro ...
Riccioli d'oro

@ TAFKA'goldilocks 'no, perché scommetto che puoi ancora avere accesso a un terminale o qualcosa di simile su XBMCubuntu mentre sembra che solo un'app sia in esecuzione graficamente, ma solo un'app è in esecuzione. Ho fatto una piccola distro una volta da zero con solo un kernel e una scatola occupata, in quel caso, anche se ci sono servizi che vengono lanciati dal kernel, puoi dire che la sola applicazione è busybox.
Kiwy,

@Kiwi Questa è una buona risposta (meglio di LFS). Ricorda: 1) Questa domanda può essere utile ad altre persone il cui scopo generale è lo stesso, quindi una serie di risposte è buona, 2) Mentre c'è una gamma di possibili soluzioni qui - vale a dire TIMTOWTDI - e alcune potrebbero essere più adatto ad un obiettivo più specifico rispetto ad altri, sono abbastanza sicuro che funzioneranno tutti e un aspetto significativo della decisione su una soluzione sarà soggettivo (ad esempio, a causa della conoscenza e dell'esperienza precedenti del PO, non della natura obiettiva del compito) .
Riccioli d'oro

Risposte:


6

Non vorrei iniziare a fare scherzi con LFS, che è un percorso del giardino che porta ad alcuni boschi scuri.

Inizia con una distro in cui hai molto controllo sull'installazione iniziale, come Arch, o un'edizione senza testa come il server Ubuntu. Il punto non è tanto quello di risparmiare spazio quanto di delimitare la complessità della configurazione di init; a partire da una distro senza testa, se l'applicazione che si desidera eseguire richiede una GUI, è possibile aggiungere ciò che è necessario per quello senza dover finire con un login GUI (ovvero il display manager o DM) avviato da init e un desktop completo ambiente per andare con esso.

Quindi vuoi imparare come configurare il sistema init secondo i tuoi scopi - nota che non puoi fare a meno di init e potrebbe essere il modo migliore per raggiungere il tuo obiettivo. Esistono tre varianti di init comunemente usate su Linux (ma ce ne sono altre ):

  • Debian usa una variante del classico init in stile Unix SysV . A partire dal jessierilascio, Debian è passato anche a systemd( https://wiki.debian.org/systemd )

  • Ubuntu e derivati ​​usano upstart .

  • Fedora, Arch e derivati ​​usano systemd .

Se non sai ancora nulla di nessuno di questi, nessuno di essi è particolarmente difficile da usare rispetto a nessuno degli altri. Se vai con uno dei due successivi, forniscono alcuni meccanismi per la retrocompatibilità con SysV, ma non ti preoccupare , NON è più semplice.1

Il punto qui è minimizzare 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 è configurato un server, A proposito, quindi è un'attività comune (nota che non puoi letteralmente avere "solo un" processo di userland in esecuzione, almeno non utilmente).

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 ~/.xinitrcaspetto simile a questo;

#!/bin/sh

myprogram

Quando lo farai startx, il tuo programma sarà l'unica cosa in esecuzione e sarà impossibile cambiare desktop o avviare qualcos'altro, in parte perché non esiste un gestore di finestre o un ambiente desktop (quindi, non ci saranno né frame di finestre o barra del titolo).

1. Per ribadire un po 'il punto: quando stai cercando questo, potresti trovare un po' di lamentela su systemd e iniziare da persone che in precedenza avevano familiarità con SysV sostenendo, ad esempio, che sono troppo complicate. Tuttavia, oggettivamente non sono più complessi di SysV (il sistema IMO è più semplice da usare, in effetti), ma la maggior parte dei cani preferisce i loro vecchi trucchi, per così dire. Questa presa sta iniziando a diminuire adesso che entrambi i sistemi sono in uso da un po 'di tempo.


1
Non puoi farne a meno initma sicuramente puoi farne a meno upstart, systemd,o sysv. initè solo un file eseguibile chiamato initche il tuo kernel invoca quando monta initramfs.Nella maggior parte dei casi questi altri tre non sono nemmeno, initma in realtà sono execinseriti da ciò init,che è comunementebusybox.
mikeserv

@mikeserv Assolutamente (e ho detto esplicitamente che queste non sono le uniche tre scelte). Nota anche che ho deliberatamente escluso busyboxperché merita un trattamento separato in una risposta separata, ma non da me.
Riccioli d'oro

Che gentile da offrire! Ma niente male.
Mikeserv,

Sarebbe interessante sapere se questo approccio funziona davvero nella pratica. Qualcuno l'ha davvero provato?
Faheem Mitha,

@FaheemMitha Se intendi quello che sto raccomandando qui (personalizza la configurazione di init), ovviamente lo fa - è così che funziona già il sistema, produresti solo una versione ridotta e semplificata (sono sicuro che sia cos'è XBMCbutu). Se vuoi dire, sostituire init con qualche eseguibile più specializzato ala busybox, probabilmente è più un problema di quanto valga la pena a meno che tu non debba farlo in questo modo - lo scopo principale di busybox è l'uso in piccoli ambienti embedded (con, ad esempio, solo alcuni MB di RAM).
Riccioli d'oro

18

Programma minimo ciao init ciao passo dopo passo

inserisci qui la descrizione dell'immagine

Compila un mondo ciao 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 di uscita, altrimenti i panici del kernel.

Poi:

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 ciao mondo su /init, che è il primo programma userland che verrà eseguito dal kernel. Avremmo anche potuto aggiungere più file d/e sarebbero accessibili dal /initprogramma quando il kernel è in esecuzione.

Quindi cdnella struttura del kernel Linux, build è come al solito ed eseguirlo 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"

E dovresti vedere una linea:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

sullo schermo dell'emulatore! Nota che non è l'ultima riga, quindi devi cercare un po 'più in alto.

Puoi anche usare i 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 la creazione di un eseguibile di collegamento dinamico, il più comune dei quali fa parte di librerie C standard come glibc.

È possibile eseguire su hardware reale con un USB acceso /dev/sdXe:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX

Grande fonte su questo argomento: Suggerimento tecnico: Come usare 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.

Prossimi passi

La prossima cosa che vuoi fare è configurare BusyBox .

BusyBox implementa le utility POSIX-y CLI di base, inclusa una shell POSIX-y, che consente di sperimentare più facilmente il sistema in modo interattivo.

Personalmente, a questo punto preferisco fare affidamento solo su Buildroot , che è un fantastico set di script che automatizza la costruzione di tutto dal sorgente e la creazione del filesystem di root.

Ho caricato un supporto altamente dettagliato e automatizzato per questo su: https://github.com/cirosantilli/linux-kernel-module-cheat


4
Questa è probabilmente la risposta più sottovalutata qui: D. Eccezionale!
msouth,

1
@msouth un po 'meno così ora :-)
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

1

se sei un po 'programmato 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 linux suse personalizzato

Saluti


1

Si tratta più di ciò che richiede il tuo "unico programma".

Puoi ancora iniziare bene a capire come mettere insieme le cose costruendo un LFS (alias " Linux From Scratch ") . Quindi aggiungerai le cose richieste dal tuo programma o otterrai una distribuzione completa perché la creazione di sottosistemi pesanti come Gnome o KDE su LFS può essere un vero problema.

Ovviamente all'inizio può essere più facile all'inizio, ma rimuovere le cose da una distribuzione completa può essere problematico: farlo in una macchina virtuale e fare copia di questa macchina virtuale ad ogni passo.

(i miei 2 centesimi)

Modifica :

Come sottolineato da SecurityBeast invece di partire da una distribuzione completa come CentOS o Ubuntu , potresti anche dare un'occhiata alla costruzione di strumenti di distribuzione come:


1

Quello che devi chiedere è di cosa ha bisogno il tuo "unico programma" e quali risorse hai.

Se necessita di una vasta selezione di librerie e binari di supporto, è meglio usare una distribuzione Linux "normale" (Debian o simile) e fare un po 'di casino con il processo di avvio.

Se ha bisogno di una selezione più ristretta di elementi di supporto, ma richiede ancora elementi come la rete o il supporto per una varietà di hardware che utilizza diversi moduli del kernel o bit di supporto userland e non si desidera lo spazio su disco in sovraccarico di una distribuzione regolare, allora suggerirei di guardare distribuzioni incorporate (buildroot o simili) o forse un approccio linux da zero (anche se può essere un mal di testa da mantenimento)

Se hai bisogno solo di ciò che può fornire un kernel non modulare e nient'altro, far funzionare il tuo binario direttamente sul kernel può funzionare ed essere l'assolo più leggero.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.