Comment créer une distribution Linux personnalisée qui exécute un seul programme et rien d'autre?

12

Comment je pourrais créer ma propre distribution Linux "personnalisée" qui exécutera un seul programme, à peu près exactement de la même manière que XBMCbuntu .

user3462992
la source
Bienvenue sur U&L, faites une visite guidée et prenez le temps d'apprendre à poser une question que voulez-vous faire? parce que la définition de l'application est assez vague et ne veut rien dire du tout, car mon conseil serait d'utiliser busyboxmais ce n'est probablement pas ce que vous voulez. veuillez donc prendre le temps nécessaire pour exprimer votre besoin et nous pourrons peut-être vous aider. N'hésitez pas à modifier votre question pour y ajouter tout élément pertinent.
Kiwy
1
Cela
@ TAFKA'goldilocks 'et bien non, car je parie que vous pouvez toujours avoir accès à un terminal ou quelque chose de similaire sur XBMCubuntu alors qu'il semble qu'une seule application fonctionne graphiquement, mais pas une seule est en cours d'exécution. J'ai fait une petite distribution une fois à partir de zéro avec seulement un noyau et une busybox, dans ce cas, même s'il y a des services qui sont lancés par le noyau, vous pouvez dire que busybox est votre seule application.
Kiwy
@Kiwi C'est donc une bonne réponse (meilleure que LFS). Gardez à l'esprit: 1) Cette question peut être utile à d'autres personnes dont l'objectif général est le même, donc une gamme de réponses est bonne, 2) Bien qu'il existe une gamme de solutions possibles ici - à savoir TIMTOWTDI - et certaines peuvent être mieux adaptés à certains objectifs plus spécifiques que d'autres, je suis sûr qu'ils fonctionneront tous et qu'un aspect important de la décision sur une solution sera subjectif (par exemple, en raison des connaissances et de l'expérience antérieures du PO, et non de la nature objective de la tâche) .
goldilocks

Réponses:

6

Je ne voudrais pas commencer à jouer avec LFS, c'est un chemin de jardin menant à des bois sombres.

Commencez avec une distribution où vous avez beaucoup de contrôle sur l'installation initiale, comme Arch, ou une édition sans tête telle que le serveur Ubuntu. L'intérêt n'est pas tant de gagner de l'espace que de délimiter la complexité de la configuration init; à partir d'une distribution sans tête, si l'application que vous souhaitez exécuter nécessite une interface graphique, vous pouvez ajouter ce qui est requis pour cela sans avoir à vous retrouver avec une connexion à l'interface graphique (aka. le gestionnaire d'affichage ou DM) démarrée par init, et un bureau complet environnement pour aller avec.

Vous souhaitez ensuite apprendre à configurer le système d'initialisation selon vos besoins - notez que vous ne pouvez pas vous passer d'init, et cela peut être le meilleur moyen d'atteindre votre objectif. Il existe trois variantes d'init couramment utilisées sur linux (mais il y en a d' autres ):

  • Debian utilise une variante de l' initialisation classique de style Unix SysV . Depuis la jessiepublication, Debian est également passée à systemd( https://wiki.debian.org/systemd )

  • Ubuntu et ses dérivés utilisent upstart .

  • Fedora, Arch et ses dérivés utilisent systemd .

Si vous ne connaissez encore rien de ces éléments, aucun n'est particulièrement difficile à utiliser que les autres. Si vous optez pour l'un des deux derniers, ils fournissent certains mécanismes de compatibilité descendante avec SysV, mais ne vous embêtez pas avec cela , ce n'est PAS plus simple. 1

Le but ici est de minimiser ce que fait init au démarrage, et c'est ainsi que vous pouvez créer un système qui exécutera une quantité minimale de logiciels pour prendre en charge l'application sur laquelle vous souhaitez vous concentrer - c'est essentiellement la façon dont un serveur est configuré, BTW, c'est donc une tâche courante (notez que vous ne pouvez pas avoir littéralement «un seul» processus utilisateur en cours d'exécution, du moins pas utilement).

Si l'application que vous souhaitez exécuter est un programme GUI (un bon exemple de la raison pour laquelle vous ne pouvez pas simplement exécuter une seule application, car les applications GUI nécessitent un serveur X), vous pouvez en avoir un ~/.xinitrcqui ressemble à ceci;

#!/bin/sh

myprogram

Lorsque vous alors startx, votre programme sera la seule chose en cours d'exécution, et il sera impossible de changer de bureau ou de démarrer quoi que ce soit d'autre, en partie parce qu'il n'y a pas de gestionnaire de fenêtres ou d'environnement de bureau (par conséquent, il n'y aura pas non plus de cadre de fenêtre ou de barre de titre).

1. Pour insister un peu sur ce point: lorsque vous effectuez des recherches sur ce sujet, vous pouvez trouver quelque prise sur systemd et upstart de personnes qui étaient auparavant familiers avec SysV affirmant, par exemple, qu'ils sont trop compliqués. Cependant, objectivement, ils ne sont pas plus complexes que SysV (le système IMO est plus simple à utiliser, en fait), mais la plupart des chiens préfèrent leurs vieux tours, pour ainsi dire. Cette prise en main commence à s'éteindre maintenant que les deux systèmes sont utilisés depuis un certain temps.

boucle d'or
la source
1
Vous ne pouvez pas faire sans , initmais certainement vous pouvez le faire sans upstart, systemd,ou sysv. initest juste un certain fichier exécutable nommé initque votre noyau quand invoque il monte initramfs.dans la plupart des cas , ces trois autres ne sont même pas , initmais ils sont en fait execé da par ce init,qui est communémentbusybox.
mikeserv
@mikeserv Absolument (et j'ai mentionné explicitement que ce ne sont pas les trois seuls choix). Notez également que j'ai délibérément exclu busyboxcar cela mérite un traitement séparé dans une réponse distincte, mais pas par moi.
goldilocks
Quelle grâce à vous d'offrir! Mais pas du tout.
mikeserv
Il serait intéressant de savoir si cette approche fonctionne réellement dans la pratique. Quelqu'un l'a vraiment essayé?
Faheem Mitha
@FaheemMitha Si vous voulez dire ce que je recommande ici (personnaliser la configuration init), bien sûr que c'est le cas - c'est ainsi que le système fonctionne déjà, vous produirez simplement une version simplifiée et simplifiée (je suis sûr que c'est ce qu'est XBMCbutu). Si vous voulez dire, en remplacement init certains ala busybox exécutable plus spécialisé, il est probablement plus d' ennuis que cela vaut la peine à moins que vous devez le faire de cette façon - l'objectif principal de busybox est pour une utilisation dans de petits environnements embarqués (avec, par exemple, seuls quelques Mo de RAM).
goldilocks
18

Programme init hello minimal minimal étape par étape

entrez la description de l'image ici

Compilez un monde bonjour sans aucune dépendance qui se termine par une boucle infinie. 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

Nous ne pouvons pas utiliser l'appel système exit, sinon les paniques du noyau.

Alors:

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"

Cela crée un système de fichiers avec notre monde bonjour /init, qui est le premier programme de l'espace utilisateur sur lequel le noyau s'exécutera. Nous aurions également pu ajouter plus de fichiers d/et ils seraient accessibles depuis le /initprogramme lors de l'exécution du noyau.

Ensuite, cddans l'arborescence du noyau Linux, la construction est comme d'habitude et exécutez-la dans 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"

Et vous devriez voir une ligne:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

sur l'écran de l'émulateur! Notez que ce n'est pas la dernière ligne, vous devez donc regarder un peu plus haut.

Vous pouvez également utiliser des programmes C si vous les liez statiquement:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}

avec:

gcc -static init.c -o init

La liaison dynamique nécessiterait la mise en place d'un exécutable de l'éditeur de liens dynamique, dont les plus courants font partie des bibliothèques standard C comme la glibc.

Vous pouvez exécuter sur du vrai matériel avec une clé USB /dev/sdXet:

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

Excellente source sur ce sujet: Astuce technique: Comment utiliser initramfs | landley.net Il explique également comment utiliser gen_initramfs_list.sh, qui est un script de l'arborescence des sources du noyau Linux pour aider à automatiser le processus.

Testé sur Ubuntu 16.10, QEMU 2.6.1.

Prochaines étapes

La prochaine chose que vous voulez faire est de configurer BusyBox .

BusyBox implémente les utilitaires de base POSIX-y CLI, y compris un shell POSIX-y, qui vous permettent d'expérimenter plus facilement avec le système de manière interactive.

Personnellement, à ce stade, je préfère me fier uniquement à Buildroot , qui est un ensemble étonnant de scripts qui automatise la construction de tout à partir de la source et la création du système de fichiers racine.

J'ai téléchargé un assistant très détaillé et automatisé pour cela à: https://github.com/cirosantilli/linux-kernel-module-cheat

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
la source
4
C'est probablement la réponse la plus sous-estimée ici: D. Impressionnant!
msouth
1
@msouth un peu moins maintenant :-)
Ciro Santilli 16 病毒 审查 六四 事件 法轮功
1

si vous êtes un peu en programmation et que vous voulez le créer à partir de zéro, vous pouvez utiliser LFS, c'est-à-dire Linux from Scratch http://www.linuxfromscratch.org/

si vous voulez personnaliser ubutnu, vous pouvez utiliser ubunt-builder et si vous le souhaitez sur la base de rpm, vous pouvez utiliser SUsE-Studio, Suse studio vous permettra de faire des suse linux personnalisés

à votre santé

Bête de sécurité
la source
1

Il s'agit davantage de ce dont votre "programme unique" a besoin.

Vous pouvez toujours avoir un bon début pour comprendre comment mettre les choses ensemble en construisant un LFS (alias " Linux From Scratch ") . Ensuite, vous ajouterez les éléments requis par votre programme ou opterez pour une distribution complète, car la construction d'un sous-système lourd comme Gnome ou KDE sur LFS peut être une véritable douleur.

Bien sûr, revenir en arrière peut être plus facile au début, mais supprimer des éléments d'une distribution complète peut être gênant: faites-le dans une machine virtuelle et copiez cette machine virtuelle à chaque étape.

(mes 2 cents)

Modifier :

Comme l'a souligné SecurityBeast au lieu de partir d'une distribution complète comme CentOS ou Ubuntu , vous pouvez également jeter un œil à la création d'outils de distribution tels que:

Ouki
la source
1

Ce que vous devez demander, c'est de quoi a besoin votre "programme unique" et de quelles ressources disposez-vous.

Si elle a besoin d'une large sélection de bibliothèques et de binaires de support, il vaut mieux utiliser une distribution linux "régulière" (Debian ou similaire) et simplement jouer un peu avec le processus de démarrage.

S'il a besoin d'une sélection plus étroite de supports, mais nécessite toujours des éléments comme la mise en réseau ou la prise en charge d'une variété de matériel utilisant différents modules du noyau ou des bits de support utilisateur et que vous ne voulez pas la surcharge d'espace disque d'une distribution régulière, je vous suggère de regarder distributions intégrées (buildroot ou similaire) ou peut-être une approche Linux à partir de zéro (bien que cela puisse être un casse-tête de maintenance)

Si vous avez besoin de ce qu'un noyau non modulaire peut fournir et rien d'autre, alors exécuter votre propre binaire directement sur le noyau peut fonctionner et être la solution la plus légère.

plugwash
la source