Un exécutable aurait-il besoin d'un noyau de système d'exploitation pour s'exécuter?

53

Je sais que lorsque le code source, en C ++ par exemple, est compilé, le compilateur génère le code machine (exécutable) qui, à mon avis, était une instruction destinée au processeur. Récemment, j'étais en train de lire sur les noyaux et j'ai découvert que les programmes ne peuvent pas accéder directement au matériel, mais doivent passer par le noyau.

Ainsi, lorsque nous compilons un code source simple, par exemple avec juste une printf()fonction, et que la compilation produit le code machine exécutable, chaque instruction de ce code machine sera-t-elle exécutée directement à partir de la mémoire (une fois que le code est chargé en mémoire par le système d'exploitation) ou chaque commande du code machine doit toujours passer par le système d'exploitation (noyau) pour être exécutée?

J'ai lu une question similaire . Il n'a pas expliqué si le code machine généré après la compilation est une instruction adressée directement à la CPU ou si elle devra de nouveau passer par le noyau pour créer la bonne instruction pour la CPU. Que se passe-t-il après le chargement du code machine dans la mémoire? Va-t-il passer par le noyau ou parler directement au processeur?

GRANZER
la source
29
Si vous écrivez du code pour un Arduino, vous n'avez pas besoin d'un système d'exploitation.
Stib
12
printfn'est pas un bon exemple. Il est explicitement défini par la spécification C comme une fonction uniquement disponible dans les implémentations "hébergées" (ce qui signifie s'exécuter sur un noyau, par opposition à "autonome", qui peut ne pas en nécessiter une). Et sur la plupart des plates-formes, il printfs’agit simplement d’une fonction fournie par votre entreprise libcqui effectue un grand nombre de tâches en votre nom (qui inclut éventuellement un appel système à imprimer sur la sortie standard). Ce n'est vraiment pas différent d'appeler libvlc_media_list_add_mediaou PyObject_GetAttr, sauf que certaines printfimplémentations sont garanties linkables sans ajouter des s non standard supplémentaires -l.
Abarnert
1
Ça existe! (pas affilié, juste pensé que c'était cool) erikyyy.de/invaders
Nonny Moose
9
Cela dépend vraiment de votre définition précise des termes "exécutable", "noyau", "exécuter", "besoin", "parler à" et "passer à travers". Sans une définition précise de ces termes, la question est sans réponse.
Jörg W Mittag le
3
@ JörgWMittag - Si vous voulez être pédant, pourquoi ne scrutez-vous que ces termes et cette question? Le terme véritablement saillant à définir est "système d'exploitation", qui s'applique de manière discutable à MS-DOS (et aux environnements d'exécution similaires à tâche unique). Si quelques personnes (mal informées) pensent que le BIOS du PC est un système d'exploitation , est-ce que tout est à prendre? Je crois que non. Le PO utilise ces mots dans un contexte qui semble raisonnable (surtout si le locuteur n'est pas anglophone) ou non technique.
sciure de bois

Réponses:

86

En tant que personne ayant écrit des programmes qui s'exécutent sans système d'exploitation, j'offre une réponse définitive.

Un exécutable aurait-il besoin d'un noyau de système d'exploitation pour s'exécuter?

Cela dépend de la façon dont ce programme a été écrit et construit.
Vous pouvez écrire un programme (en supposant que vous ayez les connaissances) ne nécessitant pas de système d'exploitation du tout.
Un tel programme est décrit comme autonome .
Les chargeurs de démarrage et les programmes de diagnostic sont des utilisations typiques des programmes autonomes.

Toutefois, le programme typique écrit et intégré dans un environnement de système d'exploitation hôte s'exécutait par défaut dans le même environnement de système d'exploitation hôte.
Des décisions et des actions très explicites sont nécessaires pour écrire et construire un programme autonome.


... la sortie du compilateur est le code machine (exécutable) que je pensais être des instructions directement à la CPU.

Correct.

Récemment, j'étais en train de lire sur les noyaux et j'ai découvert que les programmes ne peuvent pas accéder directement au matériel, mais doivent passer par le noyau.

Il s’agit d’une restriction imposée par un mode de processeur utilisé par le système d’exploitation pour exécuter des programmes, et facilitée par certains outils de compilation tels que les compilateurs et les bibliothèques.
Ce n'est pas une limitation intrinsèque à tous les programmes jamais écrits.


Ainsi, lorsque nous compilons un code source simple, par exemple avec une fonction printf (), et que la compilation produit le code machine exécutable, chaque instruction de ce code machine sera directement exécutée à partir de la mémoire (une fois le code chargé en mémoire par le système d'exploitation). ) ou chaque commande du code machine doit-elle toujours passer par le système d'exploitation (noyau) pour être exécutée?

Chaque instruction est exécutée par la CPU.
Une instruction non prise en charge ou illégale (par exemple, le processus a des privilèges insuffisants) provoquera une exception immédiate et la CPU exécutera une routine pour gérer cette condition inhabituelle.

Une fonction printf () ne doit pas être utilisée comme exemple de "code source simple" .
La traduction d'un langage de programmation de haut niveau orienté objet vers le code machine risque de ne pas être aussi simple que vous l'imaginez.
Ensuite, vous choisissez l'une des fonctions les plus complexes d'une bibliothèque d'exécution qui effectue des conversions de données et des E / S.

Notez que votre question stipule un environnement avec un système d'exploitation (et une bibliothèque d'exécution).
Une fois le système démarré et le système d'exploitation donné à l'ordinateur, des restrictions sont imposées à ce qu'un programme peut faire (par exemple, les E / S doivent être effectuées par le système d'exploitation).
Si vous envisagez d'exécuter un programme autonome (c'est-à-dire sans système d'exploitation), vous ne devez pas démarrer l'ordinateur pour exécuter le système d'exploitation.


... que se passe-t-il après le chargement du code machine dans la mémoire?

Cela dépend de l'environnement.

Pour un programme autonome, il peut être exécuté, c’est-à-dire que le contrôle est transféré en sautant à l’adresse de départ du programme.

Pour un programme chargé par le système d'exploitation, le programme doit être lié de manière dynamique aux bibliothèques partagées dont il dépend. Le système d'exploitation doit créer un espace d'exécution pour le processus qui exécutera le programme.

Va-t-il passer par le noyau ou parler directement au processeur?

Le code machine est exécuté par la CPU.
Ils ne "passent pas par le noyau" , mais "ne parlent pas au processeur" .
Le code machine (composé du code d'opération et des opérandes) est une instruction de la CPU qui est décodée et l'opération effectuée.

Peut-être que le prochain sujet à examiner concerne les modes de processeur .

sciure
la source
2
"Si vous prévoyez d'exécuter un programme autonome (c'est-à-dire sans système d'exploitation), vous ne devez pas démarrer l'ordinateur pour exécuter le système d'exploitation." n'est pas tout à fait correct. Beaucoup de programmes DOS ont été chargés après DOS, puis complètement ignorés des services DOS (en tapant directement ou en appelant directement le BIOS). Win3.x est un excellent exemple qui (sauf dans certains cas intéressants) a ignoré que DOS était présent. Win95 / 98 / Me l'a également fait. Il existe de nombreux exemples de systèmes d'exploitation prenant en charge des programmes autonomes, dont beaucoup datent de l'ère des 8/16 bits.
Eric Towers
8
@EricTowers - Par "DOS", vous voulez probablement dire MS-DOS (puisque j'ai utilisé des DOS non liés à MS ou Intel)? Vous citez un "système d'exploitation" qui ne correspond même pas aux critères de mes manuels universitaires des années 1970 sur les concepts et la conception du système d'exploitation. Les origines de MS-DOS remontent (via Seattle Computer Products) vers CP / M, qui n'est explicitement pas appelé système d'exploitation par son auteur Gary Kildall. FWIW, un système d’exploitation permettant à un programme de prendre en charge le système a échoué dans sa fonction de base de gestion des ressources système. "Il existe de nombreux exemples de systèmes d'exploitation prenant en charge des programmes autonomes" - "Support" ou incapable d'empêcher?
Sciure de bois
5
... ou ProDOS ou PC-DOS ou DR-DOS ou CBM DOS ou TRS DOS ou FLEX ...
Eric Towers
3
J'aime la terminologie "autonome" de GCC. Le mot anglais a toutes les bonnes connotations pour un code qui fonctionne sans système d'exploitation, peut-être même mieux que "standalone". Par exemple, vous pouvez compiler gcc -O2 -ffreestanding my_kernel.c special_sauce.Spour créer un fichier exécutable qui ne présuppose aucune des bibliothèques normales ou des éléments du système d’exploitation. (Bien sûr, vous auriez normalement besoin d'un script de l'éditeur de liens pour le lier utilement à un format de fichier qu'un chargeur de démarrage voudra charger!)
Peter Cordes
4
@PeterCordes "autonome" est le terme utilisé dans la norme C pour lequel OMI peut être considéré comme faisant autorité. Alternativement, un bon terme est également "non hébergé" (comme dans l'hébergé par l'OS)
Jan Dorniak
38

Le noyau est "juste" plus de code. C'est simplement que ce code est une couche qui se situe entre les parties les plus basses de votre système et le matériel réel.

Tout s’exécute directement sur la CPU, il vous suffit de passer d’une couche à l’autre pour faire quoi que ce soit.

Votre programme "a besoin" du noyau de la même manière qu'il a besoin des bibliothèques C standard pour pouvoir utiliser la printfcommande en premier lieu.

Le code de votre programme s’exécute sur la CPU, mais les branches qu’il crée pour imprimer quelque chose à l’écran passent par le code de la printffonction C , par le biais de divers autres systèmes et interpréteurs, chacun effectuant son propre traitement pour déterminer comment hello world! est en fait imprimé sur votre écran.

Supposons qu'un programme de terminal s'exécute sur un gestionnaire de fenêtres de bureau, sur votre noyau, lequel s'exécute à son tour sur votre matériel.

Il y a beaucoup plus qui se passe mais restons simples ...

  1. Dans votre programme de terminal, vous exécutez votre programme pour imprimer hello world!
  2. Le terminal voit que le programme a écrit (via les routines de sortie C) hello world!sur la console
  3. Le programme de terminal s’adresse au gestionnaire de fenêtres du bureau en disant "Je me suis hello world!écrit, pouvez-vous le mettre en place x, ys’il vous plaît?"
  4. Le gestionnaire de fenêtres du bureau monte jusqu'au noyau avec "un de mes programmes veut que votre périphérique graphique mette du texte à cette position, allez-y mec!"
  5. Le noyau transmet la requête au pilote de périphérique graphique, qui la formate de manière à ce que la carte graphique puisse comprendre.
  6. En fonction de la manière dont la carte graphique est connectée, d'autres pilotes de périphériques du noyau doivent être appelés pour transférer les données sur des bus de périphériques physiques tels que PCIe. convertisseurs
  7. Le matériel affiche des choses.

C'est une simplification excessive pour la description seulement. Voilà des dragons.

En réalité, tout ce que vous faites a besoin d'un accès matériel, qu'il s'agisse d'affichage, de blocs de mémoire, de fichiers ou autre, doit passer par un pilote de périphérique du noyau pour déterminer comment communiquer avec le périphérique approprié. Qu'il s'agisse d'un pilote de système de fichiers au-dessus d'un pilote de contrôleur de disque dur SATA qui se trouve lui-même au-dessus d'un périphérique de pont PCIe.

Le noyau sait comment relier tous ces périphériques et présente une interface relativement simple permettant aux programmes de faire des choses sans avoir à savoir comment faire tout cela eux-mêmes.

Les gestionnaires de fenêtres de bureau fournissent une couche qui signifie que les programmes n'ont pas besoin de savoir dessiner les fenêtres et de bien jouer avec les autres programmes essayant d'afficher des éléments en même temps.

Enfin, le programme terminal signifie que votre programme n'a pas besoin de savoir dessiner une fenêtre, ni parler avec le pilote de la carte graphique du noyau, ni toute la complexité liée à la gestion des tampons d'écran et du minutage d'affichage et au brassage de la lignes de données à l'écran.

Tout cela est géré par des couches sur des couches de code.

Mokubai
la source
Non seulement l' accès matériel , mais la plupart des communications entre les programmes passe également par le noyau. ce qui n'implique généralement pas au moins que le noyau configure un canal plus direct. Cependant, aux fins de la question, il est également possible et pratiqué dans des cas beaucoup plus simples de condenser tout le code en un seul programme.
Chris Stratton
En effet, votre programme de terminal n'a même pas besoin de fonctionner sur le même ordinateur que le programme qui lui écrit des choses.
jamesqf
Puisqu'il peut être nécessaire de l'indiquer explicitement dans cette question, veuillez noter que lorsque nous parlons de programmes "se parlant", c'est métaphorique.
user253751
21

Cela dépend de l'environnement. Dans de nombreux ordinateurs plus anciens (et plus simples!), Tels que l’IBM 1401, la réponse serait «non». Votre compilateur et votre éditeur de liens ont émis un "binaire" autonome qui s’exécutait sans aucun système d’exploitation. Lorsque votre programme a cessé de fonctionner, vous en avez chargé un autre qui s’exécutait également sans système d’exploitation.

Un système d'exploitation est nécessaire dans les environnements modernes, car vous n'exécutez pas un seul programme à la fois. Le partage du ou des cœurs de la CPU, de la RAM, du périphérique de stockage de masse, du clavier, de la souris et de l’affichage entre plusieurs programmes à la fois nécessite une coordination. Le système d'exploitation fournit cela. Ainsi, dans un environnement moderne, votre programme ne peut pas simplement lire et écrire le disque ou le SSD, il doit demander à l'OS de le faire en son nom. Le système d'exploitation reçoit de telles demandes de tous les programmes souhaitant accéder au périphérique de stockage, implémente des éléments tels que les contrôles d'accès (impossible pour les utilisateurs ordinaires d'écrire dans les fichiers du système d'exploitation), les met en file d'attente sur le périphérique et trie les informations renvoyées. aux bons programmes (processus).

De plus, les ordinateurs modernes (contrairement au 1401, par exemple) prennent en charge la connexion d’une très grande variété de périphériques d’E / S, et pas seulement ceux qu’IBM vous vendrait autrefois. Votre compilateur et votre éditeur de liens ne peuvent pas connaître toutes les possibilités. Par exemple, votre clavier peut être interfacé via PS / 2 ou USB. Le système d'exploitation vous permet d'installer des "pilotes de périphérique" spécifiques à un périphérique qui savent comment communiquer avec ces périphériques, mais présentent une interface commune pour la classe de périphérique au système d'exploitation. Ainsi, votre programme, et même le système d'exploitation, n'a rien à faire pour obtenir des frappes au clavier USB / PS / 2, ou pour accéder, par exemple, à un disque SATA local, à un périphérique de stockage USB ou à un stockage quelque part sur un NAS ou un SAN. Ces détails sont gérés par les pilotes de périphérique des différents contrôleurs de périphérique.

Pour les périphériques de stockage de masse, le système d’exploitation fournit à tous ceux-ci un pilote de système de fichiers qui présente la même interface avec les répertoires et les fichiers, quel que soit l’emplacement et la façon dont le stockage est implémenté. Et encore une fois, le système d'exploitation s'inquiète des contrôles d'accès et de la sérialisation. En général, par exemple, le même fichier ne devrait pas être ouvert pour l'écriture par plus d'un programme à la fois sans sauter quelques étapes (mais les lectures simultanées sont généralement acceptables).

Donc, dans un environnement polyvalent moderne, oui, vous avez vraiment besoin d'un système d'exploitation. Mais même aujourd'hui, il existe des ordinateurs tels que les contrôleurs temps réel qui ne sont pas assez compliqués pour en avoir besoin.

Dans l'environnement Arduino, par exemple, il n'y a pas vraiment de système d'exploitation. Bien sûr, il y a un tas de code de bibliothèque que l'environnement de construction incorpore dans chaque "binaire" qu'il construit. Mais comme il n'y a pas de persistance de ce code d'un programme à l'autre, ce n'est pas un système d'exploitation.

Jamie Hanrahan
la source
10

Je pense que beaucoup de réponses méconnaissent la question, qui se résume à ceci:

Un compilateur génère un code machine. Ce code machine est-il exécuté directement par un processeur ou est-il "interprété" par le noyau?

Fondamentalement, la CPU exécute directement le code machine . Il serait beaucoup plus lent que le noyau exécute toutes les applications. Cependant, il y a quelques mises en garde.

  1. Lorsqu'un système d'exploitation est présent, les programmes d'application ne peuvent généralement pas exécuter certaines instructions ou accéder à certaines ressources. Par exemple, si une application exécute une instruction qui modifie la table d’interruption du système, la CPU passe à la place à un gestionnaire d’exceptions du système d’exploitation de sorte que l’application incriminée soit terminée. De plus, les applications ne sont généralement pas autorisées à lire / écrire dans la mémoire de l'appareil. (Par exemple, "parler au matériel".) L'accès à ces régions de mémoire spéciales permet au système d'exploitation de communiquer avec des périphériques tels que la carte graphique, l'interface réseau, l'horloge système, etc.

  2. Les restrictions imposées par un système d'exploitation aux applications sont obtenues grâce à des fonctionnalités spéciales de la CPU, telles que les modes de privilège, la protection de la mémoire et les interruptions. Bien que tous les processeurs présents sur un smartphone ou un PC possèdent ces fonctionnalités, certains ne le font pas. Ces processeurs ont en effet besoin de noyaux spéciaux qui "interprètent" le code de l'application afin d'obtenir les fonctionnalités souhaitées. Un exemple très intéressant est le Gigatron , un ordinateur à 8 instructions que vous pouvez construire à partir de puces qui émulent un ordinateur à 34 instructions.

  3. Certains langages comme Java "compilent" quelque chose appelé Bytecode, qui n'est pas vraiment du code machine. Bien que, dans le passé, ils étaient interprétés pour exécuter les programmes, de nos jours, on utilise généralement la compilation Just-in-Time, qui s'exécute donc directement sur le processeur en tant que code machine.

  4. L'exécution d'un logiciel dans une machine virtuelle exigeait que son code machine soit "interprété" par un programme appelé hyperviseur . En raison de la forte demande de machines virtuelles du secteur, les fabricants de processeurs ont ajouté des fonctionnalités telles que VTx à leurs processeurs pour permettre à la plupart des instructions d'un système invité d'être exécutées directement par le processeur. Toutefois, lorsque vous exécutez un logiciel conçu pour un processeur incompatible dans une machine virtuelle (par exemple, en émulant un NES), le code de la machine devra être interprété.

Artelius
la source
1
Bien que le bytecode de Java ne soit normalement pas le code machine, il existe toujours des processeurs Java .
Ruslan
Les hyperviseurs n’ont jamais été interprètes. Bien entendu, l’interprétation est nécessaire si la machine virtuelle est un jeu d’instructions incompatible avec son hôte, mais pour une exécution de même architecture, même les premiers hyperviseurs exécutent le code directement sur la CPU (vous pouvez être dérouté par la nécessité de noyaux paravirtualisés, pour les CPU sans le support nécessaire de l'hyperviseur).
Toby Speight
5

Lorsque vous compilez votre code, vous créez un code dit "objet" qui (dans la plupart des cas) dépend des bibliothèques système ( printfpar exemple), puis votre code est encapsulé par un éditeur de liens qui ajoutera un type de chargeur de programme que votre système d'exploitation particulier peut reconnaissez (c’est pourquoi vous ne pouvez pas exécuter de programme compilé pour Windows sous Linux, par exemple) et savez comment décompresser votre code et l’exécuter. Votre programme se présente donc comme une viande dans un sandwich et ne peut être consommé que dans un paquet.

Je lisais récemment sur les noyaux et j'ai découvert que les programmes ne peuvent pas accéder directement au matériel, mais doivent passer par le noyau.

Eh bien, c'est à moitié vrai; si votre programme est un pilote en mode noyau, vous pouvez accéder directement au matériel si vous savez "parler" avec ce dernier, mais généralement (surtout pour du matériel non documenté ou compliqué), les pilotes utilisent des pilotes qui sont des bibliothèques du noyau. De cette façon, vous pouvez trouver des fonctions d'API qui savent comment parler au matériel de manière lisible par l'homme sans avoir besoin de connaître les adresses, les registres, le minutage et bien d'autres choses encore.

chaque instruction de ce code machine sera-t-elle directement exécutée à partir de la mémoire (une fois le code chargé dans la mémoire par le système d'exploitation) ou chaque commande du code de la machine devra-t-elle toujours passer par le système d'exploitation (noyau) pour être exécutée

Eh bien, le noyau est en tant que serveuse, dont la responsabilité est de vous accompagner à une table et de vous servir. La seule chose que cela ne puisse pas faire, c’est manger pour vous, vous devriez le faire vous-même. De même avec votre code, le noyau décompactera votre programme dans une mémoire et démarrera votre code qui est un code machine exécuté directement par la CPU. Un noyau a juste besoin de vous superviser - ce qui vous est permis et ce que vous n'êtes pas autorisé à faire.

il n'explique pas si le code machine généré après la compilation est une instruction adressée directement à la CPU ou devra-t-il à nouveau passer par le noyau pour créer la bonne instruction pour la CPU?

Le code machine généré après la compilation est une instruction adressée directement à la CPU. Aucun doute là-dessus. La seule chose que vous devez garder à l'esprit, tous les codes d'un fichier compilé ne sont pas le code de la machine / du processeur. Linker a enveloppé votre programme avec des métadonnées que seul le noyau peut interpréter, en guise d’indice - que faire avec votre programme.

Que se passe-t-il après le chargement du code machine dans la mémoire? Va-t-il passer par le noyau ou parler directement au processeur?

Si votre code est juste des opcodes simples comme l’ajout de deux registres, il sera exécuté directement par la CPU sans assistance du noyau, mais si votre code utilisant des fonctions de bibliothèques, ces appels sont assistés par le noyau, comme dans l’exemple avec la serveuse, si vous le souhaitez. pour manger dans un restaurant, ils vous donneraient des outils - une fourchette, une cuillère (et cela reste leurs atouts), mais ce que vous allez en faire - dépend de votre "code".

Bien, juste pour éviter les flammes dans les commentaires - c'est un modèle vraiment simpliste que j'espère aiderait OP à comprendre les choses de base, mais de bonnes suggestions pour améliorer cette réponse sont les bienvenues.

Alex
la source
3

Ainsi, lorsque nous compilons un code source simple, par exemple avec une fonction printf (), et que la compilation produit le code machine exécutable, chaque instruction de ce code machine sera directement exécutée à partir de la mémoire (une fois le code chargé dans la mémoire par système d'exploitation) ou chaque commande du code machine doit-elle toujours passer par le système d'exploitation (noyau) pour être exécutée?

Essentiellement, seuls les appels système vont au noyau. Tout ce qui concerne les E / S ou l’allocation / désallocation mémoire entraîne généralement un appel système. Certaines instructions ne peuvent être exécutées qu'en mode noyau et le processeur déclenchera une exception. Les exceptions entraînent le passage au mode noyau et le passage au code du noyau.

Le noyau ne traite pas toutes les instructions d'un programme. Il ne fait que les appels système et bascule entre les programmes en cours pour partager le processeur.

Il est impossible d'allouer de la mémoire en mode utilisateur (sans le noyau). Si vous accédez à une mémoire à laquelle vous n'êtes pas autorisé, le MMU, préalablement programmé par le noyau, remarque et provoque une exception "erreur de segmentation" au niveau de la CPU. , qui déclenche le noyau et le noyau tue le programme.

Effectuer des E / S en mode utilisateur (sans le noyau) n’est pas possible. Si vous accédez à des ports d’E / S ou à des registres pour des périphériques, ou à des adresses connectées à des périphériques exception de la même manière.


Un exécutable aurait-il besoin d'un noyau de système d'exploitation pour s'exécuter?

Dépend du type d'exécutable.

Les noyaux, en plus d'assurer la médiation de l'accès partagé à la RAM et au matériel, remplissent également une fonction de chargeur.

De nombreux "formats exécutables", tels que ELF ou PE, contiennent des métadonnées dans le fichier exécutable en plus du code et le travail du chargeur pour le traiter. Lisez les détails sanglants sur le format PE de Microsoft pour plus d'informations.

Ces exécutables font également référence à des bibliothèques ( fichiers d’ .dllobjets partagés Windows ou Linux .so) - leur code doit être inclus.

Si votre compilateur produit un fichier destiné à être traité par un chargeur de système d'exploitation et que ce dernier n'est pas présent, cela ne fonctionnera pas.

  • Pouvez-vous inclure du code qui fait le travail du chargeur?

Sûr. Vous devez convaincre le système d'exploitation de faire fonctionner votre code brut d'une manière ou d'une autre sans traiter aucune métadonnée. Si votre code appelle les API du noyau, cela ne fonctionnera toujours pas.

  • Et si elle n'appelle pas les API du noyau?

Si vous chargez cet exécutable à partir d'un système d'exploitation (c'est-à-dire s'il permet le chargement et l'exécution de code brut), il sera toujours en mode utilisateur. Si votre code accède à des choses interdites en mode utilisateur, par opposition au mode noyau, telles que la mémoire non allouée ou les adresses / registres de périphériques d'E / S, il se plantera avec des violations de privilège ou de segment (là encore, les exceptions passent en mode noyau et sont traitées là) et ne fonctionne toujours pas.

  • Que faire si vous l'exécutez en mode noyau?

Alors ça va marcher.


LawrenceC
la source
Ce n'est pas tout à fait correct. L'exigence que l'accès matériel passe par le noyau, ou même qu'il y en ait un, est une décision de conception prise affirmativement sur de nombreux systèmes aujourd'hui, mais également négative (à ce jour) sur de nombreux systèmes simples.
Chris Stratton
J'explique comment les choses se passent si A) il existe un noyau et B) si vous exécutez du code sur une CPU avec le mode utilisateur / superviseur et une MMU pour vous aider à appliquer cela. Oui, il existe des CPU et des microcontrôleurs sans MMU ou mode utilisateur / superviseur, et oui, certains systèmes fonctionnent sans utiliser toute l'infrastructure utilisateur / superviseur. La première Xbox de Microsoft ressemblait à ceci - bien qu’un processeur x86 standard avec mode utilisateur / superviseur, si je comprends bien, n’ait jamais quitté le mode noyau - le jeu chargé pouvait faire tout ce qu’il voulait.
LawrenceC
1
Le système Macintosh, avant MacOS X, était un système d'exploitation d'un ordinateur polyvalent fonctionnant sur un processeur polyvalent (famille 68000, PowerPC) prenant en charge la protection de la mémoire pendant des décennies (à l'exception des premiers ordinateurs basés sur 68000, à mon avis) et qui n'utilisait jamais cette protection. : n’importe quel programme peut accéder à n’importe quoi en mémoire.
curieuxguy
3

TL; DR Non.

Le développement Arduino vient à l’esprit comme un environnement actuel où il n’ya pas de système d’exploitation. Croyez-moi, sur l'un de ces bébés, vous n'avez pas de place pour un système d'exploitation.

De même, les jeux pour Sega Genesis n’avaient pas d’OS fourni par Sega. Vous venez de concevoir votre jeu en assembleur 68K, en écrivant directement sur du métal nu.

Ou je me suis fait les dents en faisant du travail intégré sur le processeur Intel 8051. Encore une fois, lorsque vous n’avez qu’un Eprom 2716 avec un encombrement de 2 * 8, vous n’avez pas la place pour un système d’exploitation.

Bien entendu, cela suppose une utilisation très large du mot application. En guise de question rhétorique, il convient de se demander si une esquisse Arduino est réellement une application.

dgnuff
la source
3

Bien que je ne veuille pas laisser entendre que les autres réponses ne sont pas correctes en elles-mêmes, elles fournissent beaucoup trop de détails qui, je le crains, sont encore très obscurs pour vous.

La réponse de base est que le code sera exécuté directement sur le processeur. Et non, le code machine ne "parlera" à personne, c'est l'inverse. Le processeur est le composant actif et tout ce que vous faites dans votre ordinateur sera fait par ce processeur (je simplifie un peu les choses ici mais c'est OK pour le moment). Le processeur lira le code, l'exécutera et crachera les résultats. Le code machine servira de nourriture au processeur.

Votre confusion provient de l'utilisation du mot hardware. Bien que la division ne soit plus aussi claire qu’elle était, il est préférable de penser en termes de périphériques plutôt que d’appeler simplement tout le matériel. Ainsi, s'il existe un système d'exploitation ou similaire sur votre machine, votre programme doit utiliser ses services pour accéder aux périphériques mais le processeur lui-même n'est pas un périphérique, c'est l'unité de traitement principale sur laquelle votre programme s'exécute directement.

Les noyaux, les systèmes d’exploitation et les couches intermédiaires similaires ne sont généralement utilisés que dans des systèmes plus grands où plusieurs programmes sont exécutés et où le système doit gérer la manière dont ces programmes peuvent utiliser les périphériques de l’ordinateur (assez souvent à la machine). en même temps). Dans ces cas, les programmes en cours ne peuvent accéder à ces périphériques qu'en utilisant le système qui décidera de la manière de les partager et s'assurera qu'il n'y a pas de conflits. Les petits systèmes ne nécessitant aucune gestion parmi les programmes concurrents, car aucun n’est, n’ont souvent aucun système sous-jacent et le programme unique fonctionnant normalement sur ces systèmes est plus ou moins libre de faire ce qu’il veut avec les périphériques.

Gábor
la source
2

Le BIOS qui s'exécute sur votre ordinateur à la mise sous tension est un code exécutable stocké dans la ROM. Il se compose d'instructions machine et de données. Il existe un compilateur (ou un assembleur) qui assemble ce BIOS à partir du code source. C'est un cas particulier.

D'autres cas spéciaux incluent le programme d'amorçage qui charge le noyau et le noyau lui-même. Ces cas spéciaux sont généralement codés dans un langage autre que C ++.

Dans le cas général, il est beaucoup plus pratique de demander au compilateur de produire des instructions qui appellent des services système fournis par un noyau ou par des routines de bibliothèques. Cela rend le compilateur beaucoup plus léger. Cela rend également le code compilé plus léger.

Java est à l'autre bout du spectre. En Java, le compilateur ne traduit pas le code source en instructions machine, ce terme étant généralement compris. Au lieu de cela, le code source est traduit en "instructions machine" pour une machine imaginaire appelée machine virtuelle Java. Avant de pouvoir exécuter un programme Java, il doit être associé à l'environnement d'exécution Java, qui comprend un interpréteur pour la machine virtuelle Java.

Walter Mitty
la source
2

Dans le bon vieux temps, votre programme était chargé de faire tout ce qui devait être fait pendant son exécution, soit en le faisant vous-même, soit en ajoutant du code de bibliothèque que d'autres personnes avaient écrit dans votre programme. La seule chose qui se passait à côté de cela dans l'ordinateur était le code à lire dans votre programme compilé - si vous aviez de la chance. Certains ordinateurs devaient avoir un code entré via des commutateurs avant de pouvoir en faire plus (le processus "d'amorçage" d'origine), ou même votre programme entier entré de cette façon.

Nous avons rapidement constaté qu’il était agréable d’avoir du code capable de charger et d’exécuter un programme. Plus tard, il s’est avéré que les ordinateurs étaient assez puissants pour supporter l’exécution simultanée de plusieurs programmes en faisant basculer le processeur entre eux, en particulier si le matériel pouvait y contribuer, , comment gérer plusieurs programmes essayant d’envoyer simultanément des données à l’imprimante?).

Tout cela a eu pour effet qu'une grande quantité de code d'assistance a été déplacée des programmes individuels vers le "système d'exploitation", avec un moyen normalisé d'invoquer le code d'assistance à partir de programmes utilisateur.

Et c'est là où nous en sommes aujourd'hui. Vos programmes fonctionnent à plein régime, mais chaque fois qu’ils ont besoin de quelque chose géré par le système d’exploitation, ils appellent des routines d’aide fournies par le système d’exploitation. Ce code n’est ni nécessaire ni présent dans les programmes utilisateurs eux-mêmes. Cela comprenait l’écriture sur l’affichage, la sauvegarde de fichiers, l’accès au réseau, etc.

Des micro-noyaux ont été écrits pour fournir exactement ce qui est nécessaire à un programme donné pour s'exécuter sans système d'exploitation complet. Cela présente certains avantages pour les utilisateurs expérimentés tout en abandonnant la plupart des autres. Vous voudrez peut-être lire la page Wikipedia à ce sujet - https://en.wikipedia.org/wiki/Microkernel - si vous voulez en savoir plus.

J'ai expérimenté un micro-noyau capable d'exécuter une machine virtuelle Java, mais j'ai découvert plus tard que la solution idéale pour cela est Docker.

Thorbjørn Ravn Andersen
la source
1

Dans les systèmes d’exploitation de bureau classiques, le noyau lui - même est un exécutable. (Windows a ntoskrnl.exe; Linux a vmlinux, etc.) Si vous aviez besoin d'un noyau pour qu'un exécutable puisse s'exécuter, alors ces systèmes d'exploitation ne pourraient pas exister.

Ce dont vous avez besoin d’un noyau, c’est de faire ce que fait un noyau. Autoriser l'exécution simultanée de plusieurs exécutables, arbitrer entre eux, résumer le matériel, etc. La plupart des programmes ne sont pas capables de le faire eux-mêmes avec compétence, et vous ne voudriez pas qu'ils le fassent même s'ils le pouvaient. À l'époque du DOS - que l'on pouvait à peine appeler un système d'exploitation lui-même -, les jeux utilisaient souvent le système d'exploitation un peu plus qu'un chargeur, et accédaient directement au matériel, à la manière d'un noyau. Mais avant d'acheter un jeu, vous deviez souvent savoir quelles marques et quels modèles de matériel se trouvaient sur votre machine. De nombreux jeux ne prenaient en charge que certaines familles de cartes son et vidéo, et fonctionnaient très mal sur les marques concurrentes si elles fonctionnaient du tout. Cette'

chao
la source