Comment puis-je créer un exécutable pour fonctionner sur une certaine architecture de processeur (au lieu de certains OS)?

StackOverflow https://stackoverflow.com/questions/1344631

Question

Alors je prends mon programme C ++ dans Visual Studio, décompiler, et il va cracher un petit fichier EXE agréable. Mais EXEs ne fonctionnera que sur les fenêtres, et j'entends beaucoup de choses sur la façon dont C / C ++ compile en langage assembleur, qui est exécute directement sur un processeur. Le EXE fonctionne avec l'aide de fenêtres, ou je pourrais avoir un programme qui fait un exécutable qui fonctionne sur un Mac. Mais je ne sont pas la compilation du code de C en langage assembleur, qui est processeur spécifique?

Mes Insights:

  1. Je suppose que je ne suis probablement pas. Je sais qu'il ya le compilateur Intel C, donc serait-il le code assembleur spécifique au processeur? EXEs fonctionnent sur les fenêtres, ils avantage de tonnes de choses déjà mis en place, de logiciels graphiques au framework .NET massif. Un exécutable spécifique au processeur serait littéralement à partir de zéro, avec juste le jeu d'instructions du processeur.

  2. cet exécutable serait un type de fichier? Nous pourrions être en cours d'exécution et d'ouvrir les fenêtres, mais contrôleraient passage à processeur uniquement? Je suppose que cet exécutable serait quelque chose comme un système d'exploitation, en ce sens qu'il devrait être exécuté avant toute autre chose a été démarré, et ne disposent que l'instruction de processeur réglé sur « utiliser ».

Était-ce utile?

La solution

Réfléchissons à ce que "run" signifie ...

Quelque chose doit charger les codes binaires dans la mémoire. C'est une caractéristique du système d'exploitation. Le fichier exécutable .EXE ou binaire ou d'un faisceau ou autre, est mis en forme d'une manière très spécifique à l'OS de telle sorte que le système d'exploitation peut le charger dans la mémoire.

Quelque chose doit tourner le contrôle à ces codes binaires. Il y a le système d'exploitation, encore une fois.

Les routines d'E / S (en C ++, mais cela est vrai dans la plupart des endroits) sont juste une bibliothèque qui encapsulent OS API. Zut que OS, il est partout.

Reminiscing .

Dans les temps anciens (oui, je suis ce vieux) Je travaillais sur des machines qui ne disposent pas de systèmes d'exploitation. Nous n'avons pas eu C.

Nous avons écrit des codes machine en utilisant des outils tels que « assembleurs » et « linkers » pour créer de grandes images binaires que nous pouvions charger dans la machine. Nous avons dû charger ces images binaires par un processus d'amorçage douloureux.

Nous utiliserions les touches du panneau avant pour charger le code suffisamment en mémoire pour lire un appareil pratique comme un lecteur papier bande perforée. Ceci charger un petit morceau de logiciel boot loader liaison assez standard. (Nous avons utilisé mylar donc il ne serait pas s'user.)

Alors, quand nous avons eu cette liaison chargeur en mémoire, nous pourrions nourrir la bande que nous avions préparé plus tôt avec l'assembleur.

Nous avons écrit nos propres pilotes de périphériques. Ou nous avons utilisé des routines bibliothèque qui étaient en forme de code source, coups de poing sur des bandes de papier.

Un « patch » a été fait patché morceaux de ruban de papier. De plus, comme il y avait aussi de petits insectes, nous devrions ajuster l'image de mémoire sur la base des instructions écrites à la main -. Patches qui n'a pas été mis dans la bande

Plus tard, nous avons eu de simples systèmes d'exploitation qui ont de simples API, les pilotes de périphériques simples, et quelques utilitaires comme un « système de fichiers », un « éditeur » et un « compilateur ». Il était une langue appelée Jovial, mais nous avons aussi utilisé Fortran parfois.

Nous avons dû souder les cartes d'interface série afin que nous puissions brancher un appareil. Nous avons dû écrire des pilotes de périphériques.

Bottom Line .

Vous pouvez facilement écrire des programmes C ++ qui ne nécessitent pas un système d'exploitation.

  1. En savoir plus sur les installations BIOS du matériel (ou comme BIOS) qui font partie du jeu de puces de votre processeur. La plupart du matériel moderne dispose d'un système d'exploitation simple, filaire dans la ROM qui fait la mise sous tension d'auto-test (POST), charge quelques pilotes simples, et localise les blocs de démarrage.

  2. Apprenez à écrire votre propre bloc d'amorçage. C'est la première bonne chose « logiciel » qui est chargé après le POST. Ce n'est pas si difficile. Vous pouvez utiliser différents outils de partitionnement pour forcer votre programme de bloc d'amorçage sur un disque et vous aurez un contrôle complet sur le matériel. Non OS.

  3. Découvrez comment GRUB, LILO ou BootCamp lancer un système d'exploitation. C'est pas compliqué. Une fois qu'ils sont démarrés, ils peuvent charger votre programme et vous êtes hors et courir. Ceci est un peu plus simple parce que vous créez le type de partition que le chargeur de démarrage veut charger. Base de la vôtre sur le noyau Linux et vous serez plus heureux. Ne pas essayer de comprendre comment le démarrage de Windows -. Il est trop compliqué

  4. Lire sur ELF. http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

  5. Découvrez comment les pilotes de périphériques sont écrits. Si vous n'utilisez pas un système d'exploitation, vous aurez besoin d'écrire des pilotes de périphériques.

Autres conseils

Le problème est que le système d'exploitation fait vraiment beaucoup pour commencer vos programmes. Le fichier EXE lui-même est d'en-tête des informations sur ce que Windows reconnaît, s'identifiant comme un fichier EXE. Votre application fait tout, depuis l'accès du système de fichiers pour les allocations de mémoire, à travers le système d'exploitation.

Mais oui, vous pouvez exécuter des applications compilées pour Windows / Intel sur d'autres plates-formes sans émulation. Si vous voulez exécuter votre EXE sur un Mac ou UNIX, vous devez installer un peu plus de logiciels pour faire le travail que Windows serait faire pour exécuter votre programme -. Jeter un oeil sur le projet « Wine »

Qu'est-ce que vous parlez est ce qui est connu dans le monde de l'embarqué comme une application « en métal nu ». Ils sont très commun pour des choses comme un ARM Cortex-M3 qui va (par exemple) une boîte de validateur carte de débit ou un jouet interactif, et ne dispose pas de suffisamment de mémoire ou la capacité d'exécuter un système d'exploitation complet. Ainsi, au lieu d'obtenir un compilateur « ARM / Linux » qui compiler une application pour fonctionner sur Linux sur un processeur ARM, vous obtenez un compilateur « ARM-métal nu » qui compile les choses à exécuter sur un processeur ARM sans système d'exploitation. (J'utilise ARM plutôt que x86 comme exemple, parce que les applications en métal nu x86 sont vraiment très rares ces jours-ci.)

Comme indiqué dans votre question et les autres réponses, votre application aura besoin de faire certaines choses qui seraient autrement pris en charge par le système d'exploitation.

Tout d'abord, il faut initialiser le système de mémoire, les vecteurs d'interruption, et divers autres bits de goo de bord. Typiquement, cela est quelque chose qu'un compilateur métal nu fera pour vous, mais si vous avez une carte bizarre, vous devrez peut-être lui dire comment faire. Cela fait bouger les choses du point où le conseil d'administration se met en marche au point où votre fonction principale () commence.

Ensuite, vous devez interagir avec des choses en dehors de la CPU et de la RAM. Un système d'exploitation comprend toutes sortes de fonctions pour ce faire - E / S disque, sortie écran, le clavier et la souris, réseau, etc., etc., et ainsi de suite. Sans un système d'exploitation, vous devez obtenir que d'ailleurs. Vous pouvez obtenir une partie de ce des bibliothèques de votre fabricant de matériel; par exemple, un conseil que je jouais récemment avec dispose d'un écran LED 40x200 pixels, et il est venu avec une bibliothèque avec le code pour transformer ce sur et définir des valeurs de pixels individuels sur elle. Et il y a plusieurs entreprises qui vendent des bibliothèques pour mettre en œuvre une pile TCP / IP et des choses comme ça, pour faire la mise en réseau ou tout le reste.

Considérons, par exemple, que cela rend difficile de faire même un printf de base. Lorsque vous avez un système d'exploitation, printf envoie juste un message au système d'exploitation qui dit « mettre cette chaîne sur la console », et le système d'exploitation trouve la position du curseur sur la console, et fait tous les trucs pour savoir quels pixels changer à l'écran, et quelles instructions CPU à utiliser pour modifier ces pixels, afin de le faire.

Oh, et avons-nous mentionné que vous devez d'abord comprendre comment obtenir le programme dans la CPU? Un ordinateur typique a un peu de ROM programmable qui il se chargera des instructions de son démarrage. Sur un système x86, c'est le BIOS, et il contient généralement déjà un programme pratique qui obtient la CPU a commencé, met en place l'affichage, recherche des disques, et charge un programme hors du disque qu'il trouve. Sur un système embarqué, qui est généralement où votre programme va - ce qui signifie que vous devez trouver un moyen de mettre votre programme là-bas. Souvent, cela signifie que vous avez un appareil appelé « débogueur » qui est physiquement attaché à votre conseil d'administration intégré qui charge le programme - et peut aussi faire des choses qui vous permettent de mettre en pause le processeur et de déterminer ce que son état est, afin que vous puissiez l'étape dans votre programme comme si vous étiez en cours d'exécution dans un débogueur de logiciel sur votre ordinateur. Mais je digresse.

Quoi qu'il en soit, pour répondre à votre deuxième question, cet exécutable que vous souhaitez créer est quelque chose qui est stockée dans cette ROM sur votre carte embarquée - ou vous seriez peut-être juste un peu stocker dans ROM (ce qui est, après tout, assez petit) et stocker le reste sur un lecteur flash, et le bit dans la mémoire ROM comprendrait les instructions pour obtenir le reste hors du lecteur flash. Il serait probablement stocké dans un fichier sur votre ordinateur principal (qui est, l'ordinateur Linux ou Windows sur lequel vous créez), mais qui est juste pour le stockage, il ne se présenterait pas là.

Vous remarquerez que lorsque vous avez beaucoup de ces bibliothèques ensemble, ils font un peu juste de ce qu'est un système d'exploitation fait, et il y a une sorte of cet espace entre la pile de bibliothèques et un véritable système d'exploitation. Dans cet espace va ce qu'on appelle un RTOS - « système d'exploitation en temps réel ». Les plus petits de ceux-ci sont en fait que des collections de bibliothèques qui travaillent ensemble pour faire toutes les choses exploitation-SYSTEMY, et parfois aussi inclure des choses de sorte que vous pouvez exécuter plusieurs threads à la fois (et vous pouvez avoir différents threads agissent comme différents programmes) - - bien que tout cela est tout compilé dans le même compilé « programme », et le RTOS est vraiment rien de plus qu'une bibliothèque que vous avez inclus. Les plus grands commencent à stocker des parties du code dans des endroits séparés, et je pense que certains d'entre eux peuvent même charger des morceaux de code hors de disques - tout comme Windows et Linux font lors de l'exécution d'un programme. Il est en quelque sorte d'un continuum, plutôt que d'un ou l'autre / ou.

Le système FreeRTOS est un RTOS open-source qui est vers l'extrémité inférieure de l'espace RTOS; ils pourraient être un bon endroit pour regarder quelques-uns si vous êtes plus intéressé. Ils ont quelques exemples d'applications x86, qui vous donnera une idée de ce genre de systèmes x86 courrait un métal nu ou d'un programme basé sur RTOS et comment vous compiler quelque chose à courir sur un; lien ici: http://www.freertos.org/a00090.html#186 .

L'ordinateur n'est pas la CPU. Pour faire quelque chose d'utile, la CPU doit être connecté à la mémoire et les contrôleurs IO et d'autres appareils. Un système d'exploitation prend soin d'abstraire tous que des programmes en cours d'exécution. Donc, si vous voulez écrire un programme qui fonctionne sans système d'exploitation, votre programme devra reproduire au moins certaines caractéristiques d'un système d'exploitation: La prise en charge du BIOS lors du processus de démarrage, l'initialisation des périphériques, la communication avec le contrôleur de disque pour charger le code et des données, la communication avec le contrôleur d'affichage pour afficher des informations à l'utilisateur, qui communique avec le contrôleur de clavier et le contrôleur de souris pour lire une entrée utilisateur etc etc etc.

Sauf si vous construisez un système embarqué avec du matériel spécialisé, il est inutile de le faire. En outre, l'exécution de votre programme signifierait que l'utilisateur aurait à renoncer à l'exécution d'autres programmes. Bien que cela puisse être acceptable pour un aujourd'hui ou WordStar ATM en 1984, ces jours-ci les gens désapprouvent ne pas être en mesure de vérifier le courrier électronique tout en écoutant de la musique.

Bien sûr, ils existent. Ils sont appelés compilateurs croisés . Par exemple, voilà comment je peux programmer pour la plate-forme iPhone en utilisant Xcode.

Un type de compilateur lié est celui qui compile une plate-forme virtuelle. Voilà comment Java fonctionne .

Tout compilateur / jeu d'outils donné produit code pour une combinaison processeur particulier / OS. Ainsi, votre Visual Studio compile par exemple produit code pour x86 / Windows. Ce .EXE ne fonctionne que sur x86 / Windows et non (par exemple) ARM / Windows (utilisé par certains téléphones cellulaires).

Pour produire du code pour une combinaison processeur / système d'exploitation autre que ce que vous utilisez le compilateur sur exige ce qui est généralement considéré comme un compilateur croisé. Si vous disposez d'un abonnement Visual Studio professionnel complet, vous pouvez obtenir le compilateur croisé ARM, ce qui vous permettra de produire des fichiers ARM / Windows .EXE qui ne fonctionne pas sur votre ordinateur de bureau, mais fonctionnera sur un téléphone portable à base d'ARM / Windows ou palmaire.

Oui, vous pouvez faire un fichier exécutable qui fonctionne sur le « métal nu » d'un processeur. De toute évidence, c'est comment le système d'exploitation noyaux travail. La principale chose que vous devez faire est de créer un exécutable qui utilise pas de bibliothèques que ce soit. Cependant, la restriction « non bibliothèques » inclut la bibliothèque standard C! Cela signifie donc pas malloc, pas printf, etc. Vous devez être fondamentalement votre propre système d'exploitation et de gérer la mémoire et les E / S vous. Cela va inévitablement besoin d'un peu de travail directement dans l'assemblage à un moment donné.

Vous perdez également plusieurs autres produits de luxe, comme principal (), qui ne peut être le point de départ de votre programme depuis principal () est quelque chose qui est invoquée par le système d'exploitation et l'environnement d'exécution C.

Tout à fait! C'est ce que la programmation embarquée est. Comme beaucoup l'ont probablement déjà dit le système d'exploitation fait un peu pour vous. Et même dans le monde de l'embarqué sans système d'exploitation un certain nombre des outils de développement fournira le code de démarrage pour obtenir suffisamment en cours d'exécution du processeur pour accéder à votre programme. Certains / plusieurs bibliothèques fournissent plein fouet C / C ++ afin que vous pouvez appeler des fonctions comme memcpy () et parfois même malloc () et printf ().

Nous vous invitons à fournir à chaque ligne de code et toutes les instructions et ne pas utiliser un ensemble d'outils de développement, mais toujours utiliser un compilateur comme gcc par exemple. Certains des formats binaires sont communs à ceux qui sont gérés sur les systèmes d'exploitation comme Elf par exemple. Vous pouvez exécuter des fichiers elf sur Linux, mais aussi le résultat de votre programme embarqué dans un binaire elfe. Le processeur ne peut pas exécuter elfe dans ce format, mais quel que soit le programme de bal de démarrage ou de la RAM dans certains cas extraira le programme binaire à partir du fichier elfe, un peu comme un système d'exploitation extraire le programme à exécuter à partir d'un fichier elfe. EXE est pas un de ces formats de fichier. Votre compilateur application Windows préférée est probablement pas un compilateur intégré soit bien que vous pouvez parfois utiliser un pour faire les choses de langage de haut niveau et puis utilisez un assembleur et éditeur de liens alternatif. Plus de travail que cela vaut la peine habituellement. Par exemple, vous écrivez une fonction C (qui ne fait aucun appel de bibliothèque ou système), compilation qui à un objet. Écrivez votre propre ou de trouver un utilitaire pour extraire le binaire compilé à partir de cet objet, le convertir en un autre format d'objet ou d'assembleur (désassembler). Ajoutez votre code de démarrage et d'autres assemblage à lui. Assembler et relier tout ensemble comme un programme intégré. Je l'ai fait une fois avec Microsofts juste intégré C visuel pour voir comment il mesure à d'autres compilateurs, il était pas horrible, mais certainement pas la peine de piratage pour obtenir à la sortie.

Chaque processeur de celui de votre ordinateur à celui de votre téléphone cellulaire ou micro-ondes a avoir trop du code de démarrage. Ce code ne fonctionne pas sur un système d'exploitation. Ce code utilise les compilateurs identiques ou similaires que les applications du système d'exploitation utilisé. Pour certains appareils que le code met le processeur et la mémoire et des périphériques et hors de la puce dans un état où le système d'exploitation peut être démarré. De là, le système d'exploitation prend le relais. Sur votre ordinateur ce serait le BIOS suivi du bootloader, puis finalement le système d'exploitation, dos, Windows, Linux, etc.

Le principal problème est le format de fichier. PE est très différent de ELF (utilisé dans les systèmes unix-like). Un programme de PE valide ne peut pas être un ELF valide. Donc, soit vous chargez le binaire dynamique avec des entrées différentes ou vous devez abandonner.

Autre que cela, avec la connaissance des services OS, la valeur des registres au démarrage, etc. votre code peut probablement détecter facilement et de manière fiable quel système d'exploitation alors que vous exécutez et agir en conséquence (Certains malwares exactement ce que fait). Un autre défi est alors le code réutilise au lieu d'avoir deux ou plusieurs programmes différents dans le même binaire. Fondamentalement, vous devez écrire un émulateur, au moins pour les services dont vous avez besoin.

Ne pas oublier aussi les bibliothèques Windows. Regardez dans l'intervalle QT et GTK +

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top