Analyse expérimentale: https://www.zhihu.com/column/c_142990858
Linux est un système d'exploitation open source. Les utilisateurs peuvent adapter et modifier le noyau en fonction de leur propre système pour personnaliser des systèmes avec des fonctions plus appropriées et une efficacité opérationnelle plus élevée. Par conséquent, la compilation du noyau Linux est une compétence de base nécessaire pour le développement du noyau.
L'ajout de nouveaux appels système au besoin dans le système est une méthode courante pour modifier le noyau. Grâce à cette expérience, les lecteurs doivent comprendre le processus des appels système de traitement du système Linux et la méthode d'ajouter les appels système.
(1) Ajoutez un appel système pour implémenter la fonction de modification ou de lecture de la bonne valeur du processus spécifié et renvoyez la dernière valeur agréable et priorité du processus. Il est recommandé d'appeler le prototype comme:
int mysetnice (pid_t pid, int drapeau, int nicevalue, void __User * prio, void __User * Nice);
Signification du paramètre: PID: ID de processus.
Indicateur: si la valeur est 0, cela signifie lire la bonne valeur; Si la valeur est 1, cela signifie modifier la bonne valeur.
Prio, Nice: la priorité actuelle et la bonne valeur du processus. Valeur de retour: retournez 0 lorsque l'appel système est réussi et renvoyez le code d'erreur Efault lorsque l'appel système échoue.
(2) Écrivez un test d'application simple ajouté en (1).
(3) Si la fonction du noyau de Linux est appelée dans le programme, il est nécessaire de lire le code source de la fonction pertinente en profondeur.
Le mécanisme du module fourni par Linux peut étendre dynamiquement les fonctions Linux sans recompiller le noyau et a été largement utilisé dans la mise en œuvre de nombreuses fonctions du noyau Linux. Dans cette expérience, nous apprendrons les concepts de base, les principes et les techniques de mise en œuvre des modules, puis utiliserons le module du noyau pour programmer et accéder aux informations de base du processus, approfondissant ainsi notre compréhension des concepts de processus et des techniques de programmation de modules de maîtrise.
(1) Concevoir un module qui nécessite de répertorier les noms de programme, les numéros PID, l'état du processus et les priorités de processus de tous les threads de noyau du système.
(2) Concevoir un module avec des paramètres, dont les paramètres sont le numéro PID d'un processus. La fonction de ce module est de répertorier les informations familiales du processus, y compris le nom du programme et le numéro de PID du processus parent, du processus frère et du processus enfant.
(3) Veuillez lire davantage la mise en œuvre du code source des fonctions du noyau pertinentes utilisées dans le programme en fonction de votre propre situation.
(1) Connaissez l'interface de commande de Linux.
(2) Grâce à l'application de programmation des appels système connexes pour le contrôle des processus Linux, nous approfondirons davantage notre compréhension des concepts de processus, clarifierons la connexion et les différences entre les processus et les programmes, et comprendre la signification spécifique de l'exécution simultanée des processus.
(3) Grâce à l'utilisation du mécanisme de communication du pipeline Linux, du mécanisme de communication des files d'attente de messages et du mécanisme de communication de la mémoire partagée, approfondissez la compréhension des différents types de méthodes de communication de processus.
(4) approfondir la compréhension du mécanisme de synchronisation du sémaphore à travers l'application de sémaphores POSIX dans Linux. (5) Veuillez lire et analyser davantage la mise en œuvre du code source du noyau des appels système connexes en fonction de votre propre situation.
(1) Familier avec les commandes Linux communes: PWD, UserAdd, Passwd, Who, PS, PSTREE, KILL, TOP, LS, CD, MKDIR, RMDIR, CP, RM, MV, CAT, More, Grep, etc.
(2) implémenter un shell simulé:
Écrivez trois programmes différents CMD1.C, CMD2.C et CMD3.C. Les fonctions de chaque programme sont personnalisées et compilées en fichiers exécutables CMD1, CMD2 et CMD3 respectivement. Ensuite, rédigez un programme pour simuler la fonction du programme Shell. Il peut créer un processus d'enfant pour la commande correspondante en fonction de la chaîne entrée par l'utilisateur (représentant le nom de commande correspondant) et le laisser exécuter le programme correspondant. Le processus parent attend que le processus de l'enfant se termine, puis attend que la commande suivante soit reçue. Si la commande reçue est sortie, le processus parent se termine; Si la commande reçue est une commande non valide, "commande non trouvée" s'affiche et vous continuez à attendre.
(3) Mettre en œuvre un programme de communication de pipeline:
Un pipeline est créé par le processus parent, puis 3 processus enfants sont créés, et ces trois processus enfants utilisent le pipeline pour communiquer avec le processus parent: le processus d'enfant envoie des informations, et le processus parent et les trois autres processus enfants reçoivent les informations après tous les messages d'envoi. Le contenu spécifique de la communication peut être conçu en fonction de vos propres besoins, et il est nécessaire de tester diverses situations dans le processus de lecture et d'écriture de blocage, de tester la taille par défaut du pipeline et d'utiliser le mécanisme de sémaphore POSIX pour obtenir un accès mutuellement exclusif au pipeline entre les processus. Exécutez le programme pour observer le nombre réel d'octets lus et écrivez par le processus et le blocage du processus et le réveil dans diverses circonstances.
(4) Utilisez le mécanisme de communication de la file d'attente de messages de Linux pour réaliser la communication entre deux threads:
Écrivez un programme pour créer deux threads: thread de l'expéditeur et thread Recevoir, où le thread de l'expéditeur exécute la fonction Sender (), qui crée une file d'attente de messages, puis boucles pour attendre que l'utilisateur entre une chaîne de caractères via le terminal, envoyant la chaîne de caractères au fil du récepteur via la file d'attente de messages jusqu'à ce que l'utilisateur entre "quitter"; Enfin, il envoie un message "fin" au fil du récepteur et attend la réponse du récepteur. Après le message de réponse, il affiche les informations de réponse reçues sur l'écran du terminal, supprime la file d'attente de messages pertinente et met fin à l'exécution du programme. Le thread du récepteur exécute Recee (), qui reçoit des messages de l'expéditeur via la file d'attente de messages et affiche le message sur l'écran du terminal jusqu'à ce qu'il reçoive un message avec "Fin". À l'heure actuelle, il envoie un message de réponse "sur" à l'expéditeur, mettant fin à l'exécution du programme. Utilisez des sémaphores sans nom pour atteindre la synchronisation et l'exclusion mutuelle entre deux threads.
(5) Utilisez le mécanisme de communication de la mémoire partagée de Linux pour réaliser la communication entre deux processus:
Écrivez un expéditeur de programme, qui crée une mémoire partagée, puis attend que l'utilisateur saisisse une chaîne de caractères via le terminal, et envoie la chaîne de caractères au récepteur via la mémoire partagée; Enfin, il attend la réponse du récepteur. Après avoir reçu le message de réponse, il affiche les informations de réponse reçues sur l'écran du terminal, supprime la mémoire partagée et termine l'exécution du programme. Écrivez un programme de récepteur, qui reçoit des messages de l'expéditeur via la mémoire partagée, affiche le message sur l'écran du terminal, puis envoie un message de réponse "sur" à l'expéditeur via la mémoire partagée, mettant fin à l'exécution du programme. Utilisez un sémaphore Semaphore ou System V nommé pour obtenir une utilisation mutuellement exclusive et synchrone de la mémoire partagée par deux processus.
Grâce à la gestion de l'espace de stockage de fichiers spécifique, de la structure physique des fichiers, de la structure du répertoire et des opérations de fichiers, nous approfondirons notre compréhension de la structure de données interne, des fonctions et du processus d'implémentation du système de fichiers.
(1) Ouvrez un espace disque virtuel en mémoire en tant que partition de stockage de fichiers et implémentez un système de fichiers simple dans un système unique utilisateur unique basé sur des répertoires à plusieurs niveaux. Lors de la sortie du système de fichiers, le système de fichiers virtuel doit être enregistré sur le disque en tant que fichier afin qu'il puisse être restauré dans l'espace disque virtuel en mémoire la prochaine fois.
(2) L'allocation de l'espace de stockage de fichiers peut être effectuée par allocation de liens explicite ou d'autres méthodes.
(3) Vous pouvez choisir des diagrammes de bits ou d'autres méthodes pour gérer l'espace disque gratuit. Si le bitmap est utilisé pour gérer l'espace de stockage des fichiers et utiliser l'allocation de liens explicites, le bitmap peut être fusionné en graisse.
(4) La structure du répertoire de fichiers adopte une structure de répertoire à plusieurs niveaux. Pour plus de simplicité, les nœuds d'index peuvent être utilisés, chaque élément de répertoire doit contenir des informations telles que le nom de fichier, l'adresse physique, la longueur, etc., et les fichiers de lecture et d'écriture peuvent également être protégés via des éléments de répertoire.
(5) Les commandes de fonctionnement suivantes sont nécessaires: