Ce projet montre comment créer rapidement un système d'exploitation Linux compact et entièrement fonctionnel. L'adresse du projet est https://github.com/superconvert/smart-os

Pourquoi choisissons-nous la version du serveur pour la production?
La version du serveur ne contient pas la plupart des packages sur lesquels le système de fenêtre dépend; Si le système est livré avec ces packages, il y aura des problèmes avec plusieurs versions du package, des problèmes de compilation, des problèmes de dépendance, des problèmes de liaison et des problèmes d'exécution, ce qui entraînera beaucoup d'interférence à notre travail. De plus, la résolution de ces problèmes n'a pas de sens, nous avons besoin de versions pures de packages de dépendance
Pourquoi le système de fenêtres fonctionne-t-il si grand?
Tous les packages (à l'exception des outils) que nous installons en utilisant APT, théoriquement, nous devons compiler le code source, y compris les dépendances et les adhérences du package, qui doivent être résolues. Il s'agit d'une charge de travail extrêmement énorme. Il n'y a aucun moyen, il n'y a rien sur le nouveau système, et l'environnement requis doit être fourni par nous. Le projet A dépend du package B, le package B dépend du package C, le package C et le package C dépend du package d. Tout ce que nous avons à faire est de compiler tous les packages!
Ce script a été réalisé sur Ubuntu 18.04. D'autres systèmes ne devraient pas être beaucoup modifiés. Les amis qui en ont besoin peuvent le modifier eux-mêmes.
Préparez l'environnement du système. Étant donné que le noyau doit être compilé, vous devez installer l'environnement requis pour la compilation du noyau. Étant donné que BusyBox doit être compilé, vous pouvez installer vous-même l'environnement requis au besoin.
./00_build_env.shCompiler le code source (noyau, glibc, busybox, gcc, binutils)
./01_build_src.shCréer un disque système (important, cette étape installe le système dans un fichier système)
./02_build_img.shExécutez le système Smart-OS
./03_run_qemu.sh 或 ./04_run_docker.shEst-il facile de créer un système d'exploitation? L'espace disque peut être élargi arbitrairement, accessible en ligne et peut être étendu au besoin. Je l'ai essayé avec succès et exécuté le serveur de streaming SMART_RTMPD dans Smart-OS
+----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+
| Host | Container 1 | Container 2 |
| | | |
| +------------------------------------------------+ | +-------------------------+ | +-------------------------+ |
| | Newwork Protocol Stack | | | Newwork Protocol Stack | | | Newwork Protocol Stack | |
| +------------------------------------------------+ | +-------------------------+ | +-------------------------+ |
| + + | + | + |
| ............... | .................... | ........................... | ................... | ..................... | .................... | .................... |
| + + | + | + |
| +-------------+ +---------------+ | +---------------+ | +---------------+ |
| | 192.168.0.3 | | 192.168.100.1 | | | 192.168.100.6 | | | 192.168.100.8 | |
| +-------------+ +---------------+ +-------+ | +---------------+ | +---------------+ |
| | eth0 | | br0 | < --- > | tap0 | | | eth0 | | | eth0 | |
| +-------------+ +---------------+ +-------+ | +---------------+ | +---------------+ |
| + + + | + | + |
| | | | | | | | |
| | + +------------------------------+ | | |
| | +-------+ | | | |
| | | tap1 | | | | |
| | +-------+ | | | |
| | + | | | |
| | | | | | |
| | +-------------------------------------------------------------------------------------------+ |
| | | | |
| | | | |
+--------------- | ------------------------------------------------+-----------------------------------------+-----------------------------------------+
+
Physical Network (192.168.0.0/24)Étant donné que Smart-OS installe la bibliothèque GLIBC Dynamic, cela s'appuie fortement sur le dynamique Library Loader / Linker LD-Linux-X86-64.So.2. Étant donné que les applications sont liées via une compilation dynamique, lorsqu'une application qui nécessite une liaison dynamique est chargée par le système d'exploitation, le système doit localiser et charger tous les fichiers de bibliothèque dynamique dont il a besoin. Ce travail est effectué par ld-liux.so.2. Lorsque le programme est chargé, le système d'exploitation remettra le contrôle à LD-Linux. Aussi au lieu de l'adresse d'entrée normale du programme. ld-linux.so.2 recherchera et chargera tous les fichiers de bibliothèque requis, puis remettra le contrôle sur le portail de départ de l'application. LD-LINUX-X86-64.SO.2 est en fait la chaîne douce de Ld-Linux.SO.2. Il doit exister sous /lib64/ld-linux-x86-64.so.2. Sinon, notre busybox compilé dynamiquement dépend de la bibliothèque GLIBC. Le chargement de la bibliothèque GLIBC nécessite LD-Linux-X86-64.So. S'il n'existe pas dans le répertoire / lib64, cela entraînera la panation directe du système. Ce numéro nécessite une attention particulière! ! !
Qemu a généralement une petite fenêtre après le démarrage. Une fois qu'une erreur se produit, il n'y a essentiellement aucun moyen de lire le journal d'erreur. Ensuite, vous devez ajouter Console = TTYS0 à l'élément de démarrage de Grub. Dans le même temps, QemU-System-x86_64 ajoute une sortie de port série au fichier -serial Fichier: ./ qemu.log, donc le débogage est beaucoup plus pratique. Après le débogage, vous devez supprimer la console = TTYS0. Sinon, le contenu dans /etc/init.d/rcs ne peut pas être affiché.
La version de GLIBC que nous avons compilée est généralement plus élevée que la version fournie avec le système. Nous pouvons écrire un programme de test main.c pour tester si GLIBC est compilé avec succès. Par exemple:
# include < stdio.h >
int main () {
printf ( " Hello glibc n " );
return 0 ;
}Nous compilons
gcc -o test main.c -Wl,-rpath=/root/smart-os/work/glibc_install/usr/lib64 Nous exécutons avec succès le programme ./test, et nous rapportons généralement une erreur similaire à ce /lib64/libc.so.6: version `glibc_2.28 'n'est pas trouvée ou les segments de programme directement. En fait, c'est la raison pour laquelle il n'y a pas de chargeur / linateur de bibliothèque dynamique spécifié et d'environnement système. Habituellement, lorsque nous compilons la bibliothèque GLIBC, le répertoire de compilation générera automatiquement un fichier de script testrun.sh et nous exécutons le programme dans le répertoire de compilation.
./testrun.sh ./test Cela se fait généralement avec succès. Nous pouvons également enregistrer la phrase suivante dans un script, et il est également acceptable d'exécuter le test.
exec env /root/smart-os/work/glibc_install/lib64/ld-linux-x86-64.so.2 --library-path /root/smart-os/work/glibc_install/lib64 ./testComment suivre les bibliothèques chargées par un programme exécutable? Utilisez simplement ld_debug = libs ./test. Nous préchargez la bibliothèque et forçons la précharge de la bibliothèque pour utiliser ld_preload pour forcer la précharge de la bibliothèque
Lorsque nous compilons le Caire, nous rencontrons généralement de nombreux problèmes. Que devons-nous faire s'il y a un problème avec la compilation du Caire? Certains messages d'erreur sont difficiles à rechercher sur Internet pour voir le fichier config.log généré pendant la compilation. Les messages d'erreur sont très détaillés! Vous pouvez résoudre le problème en fonction des informations rapides
À propos des variables du système Init de Busybox, même si les paramètres du noyau de Grub sont utilisés, il n'est pas possible de transmettre des variables d'environnement. L'initiale de Busybox générera automatiquement le chemin de variable d'environnement par défaut, donc le code source doit être modifié pour prendre en charge les chemins personnalisés. Bien sûr, le mode de connexion du shell lira / etc / profil. Pour le mode non-login, ce mode n'est pas valide, il y a donc des limites à passer / etc / profil.
Cette connaissance implique des connaissances relativement importantes. Il y a relativement peu d'articles qui introduisent spécifiquement la compilation et l'utilisation de XFCE4 en Chine, y compris à l'étranger. J'ai également traversé la rivière en sentant les pierres et essayé de démontrer clairement ces connaissances. Je vais ouvrir un chapitre spécial pour expliquer cela. Pour la transplantation XFCE4 dans Smart-OS, il révélera les secrets du système graphique aux Chinois. Pour plus de détails, veuillez consulter XFCE4.md.
La charge de travail d'intégration de l'ensemble du système graphique est particulièrement énorme, impliquant tous les aspects du système. Il y a relativement peu d'informations systématiques sur cet aspect à l'étranger et presque moins en Chine. L'objectif est de bricoler tous les environnements et les projets open source personnels pour rendre l'intégralité du système graphique intact. Smart-OS n'est pas le premier, mais c'est essentiellement les trois premiers. Je ne sais pas encore. L'ensemble du processus d'intégration est très long et j'ai rencontré de nombreux problèmes. Je ne parlerai pas de ces tâches répétitives grâce à un débogage et à une compilation continus. La charge de travail est particulièrement énorme. Je peux presque décrire mon travail dur. Ce n'est absolument pas une exagération de décrire mon travail. Deuxièmement, j'ai rencontré de nombreux points de connaissance, dont beaucoup ont été appris et vendus immédiatement. J'avais besoin de comprendre rapidement le mécanisme de travail, de causer le problème, puis de résoudre le problème. Parlons à peu près de l'idée globale, ce qui facilitera les nouveaux chercheurs pour comprendre rapidement les idées, fournir des conseils sur la maintenance du système et fournir un modèle pour résoudre les problèmes du système.
Le répertoire USR détaille l'abréviation de la ressource système USR = UNIX. La bibliothèque / lib est une bibliothèque au niveau du noyau, / usr / lib est une bibliothèque au niveau du système, et / usr / local / lib est une bibliothèque au niveau de l'application; / lib contient de nombreuses bibliothèques utilisées par des programmes exécutables dans / bin && / sbin. / usr / lib presque toutes les bibliothèques référencées par des programmes exécutables du système sont installés ici, et / usr / local / bin de nombreuses bibliothèques référencées par des programmes exécutables au niveau de l'application sont placés ici
RAMFS:
RAMFS est un système de fichiers très simple. Il utilise directement le mécanisme de cache existant du noyau Linux (donc son code d'implémentation est très petit. Pour cette raison, la fonction RAMFS ne peut pas être bloquée via des paramètres de configuration du noyau. C'est une propriété naturelle du noyau). Il utilise la mémoire physique du système pour créer un système de fichiers basé sur la mémoire de taille dynamique. Le système ne le recyclera pas et seuls les utilisateurs de racine l'utilisent.
TMPFS:
Le TMPFS est une dérivée de RAMFS, qui ajoute des limites de capacité et permet d'écrire les données pour les échanges en fonction des RAMF. En raison de l'ajout de ces deux fonctionnalités, les utilisateurs ordinaires peuvent également utiliser les TMPF. Les TMPF occupent la mémoire virtuelle, pas toutes les RAM, et ses performances peuvent ne pas être aussi élevées que Ramfs
Ramdisk:
Ramdisk est une technologie qui utilise une zone en mémoire comme disque physique. On peut également dire que Ramdisk est un périphérique de bloc créé dans un morceau de mémoire pour stocker les systèmes de fichiers. Pour les utilisateurs, Ramdisk peut être traité également avec la partition de disque dur habituelle. Le système stockera également un cache correspondant en mémoire, polluant le cache CPU, les mauvaises performances et nécessitera une prise en charge correspondante du pilote.
rootfs:
RootFS est une instance de RAMFS spécifiques (ou TMPFS, si TMPFS est activé), il existe toujours dans les systèmes Linux2.6. ROOTFS ne peut pas être désinstallé (plutôt que d'ajouter du code spécial pour maintenir les listes liées vides, il est préférable d'ajouter toujours des nœuds rootfs, il est donc pratique pour la maintenance du noyau. Rootfs est une instance vide de RAMFS et prend très peu d'espace). La plupart des autres systèmes de fichiers sont installés sur ROOTFS puis l'ignorent. Il s'agit de l'initialisation de démarrage du noyau du système de fichiers racine.
Rootfs est divisé en rootfs virtuel et réel rootfs.
Les Rootfs virtuels sont créés et chargés par le noyau lui-même et n'existent que dans la mémoire (l'initiation suivante est également implémentée sur cette base), et son système de fichiers est de type TMPFS ou de type RAMFS.
Real rootfs signifie que le système de fichiers racine existe sur le périphérique de stockage. Pendant le processus de démarrage, le noyau montera ce périphérique de stockage sur le ROOTFS virtuel, puis changera le nœud / répertoire vers ce périphérique de stockage. De cette façon, le système de fichiers sur le périphérique de stockage sera utilisé comme système de fichiers racine (l'initiant inimitramdisk est implémenté sur cette base), et ses types de systèmes de fichiers sont plus riches, qui peuvent être EXT2, YAFFS, YAFFS2, etc., qui sont déterminés par le type de dispositif de stockage spécifique.
Notre système de fichiers de démarrage doit en fait préparer des fichiers pour rootfs, afin que le noyau puisse s'exécuter comme nous le souhaitons. Dans les premiers systèmes Linux, seuls les disques durs ou les disquettes étaient généralement utilisés comme périphériques de stockage pour le système de fichiers racine Linux, il est donc facile d'intégrer les pilotes de ces appareils dans le noyau. Cependant, dans les systèmes intégrés d'aujourd'hui, le système de fichiers racine peut être enregistré sur divers périphériques de stockage, y compris SCSI, SATA, U-Disk, etc. Par conséquent, il n'est évidemment pas très pratique de compiler tout le code du pilote de ces appareils dans le noyau. Dans le module du noyau mécanisme de chargement automatique UDEV, nous voyons que l'UDEVD peut réaliser le chargement automatique du module du noyau, nous espérons donc que si le pilote du périphérique de stockage stockant le système de fichiers racine peut également réaliser le chargement automatique, ce serait génial. Cependant, il y a une contradiction ici. Udevd est un fichier exécutable. Il est impossible d'exécuter UDEVD avant le montage du système de fichiers racine. Cependant, si UDEVD n'est pas démarré, le pilote qui stocke le périphérique de système de fichiers racine ne peut pas être automatiquement chargé et le nœud de périphérique correspondant ne peut pas être établi dans le répertoire / dev. Afin de résoudre cette contradiction, un INITRD basé sur Ramdisk (Disk RAM initialisé de bootloader) a émergé. IniTRD est un répertoire racine petit compacté. Ce répertoire contient les modules de pilote nécessaires, les fichiers exécutables et les scripts de démarrage à l'étape de démarrage, et comprend également l'UDEVD (démon qui implémente le mécanisme UDEV). Lorsque le système démarre, le chargeur de démarrage lira le fichier initrd en mémoire, puis transmettra l'adresse de démarrage et la taille du fichier initrd en mémoire au noyau. Pendant le processus d'initialisation, le noyau décompressera le fichier initrd, puis montera le répertoire ROOT UNTRD Unzippepied, puis exécutera le script / init dans le répertoire racine (init dans le format CPIO est / init, tandis que Initrd dans le format d'image <également connu sous le nom de INITRD des périphériques anciens ou initrd dans le format de miroir de fichier traditionnel> est / INTRC). Vous pouvez exécuter UDEVD dans le système de fichiers INITRD dans ce script, laissez-le automatiquement les pilotes REALFS (Système de fichiers réel) pour stocker le périphérique et établir les nœuds de périphérique nécessaires dans le répertoire / dev. Une fois UDEVD chargé automatiquement le pilote de disque, vous pouvez monter le répertoire racine réel et passer à ce répertoire racine.