Écriture d'un système d'exploitation multitâche pour un processeur sans MMU

9

J'ai pensé à écrire un système d'exploitation pour certains des processeurs ARM. Il existe de nombreux ordinateurs à carte unique populaires avec ARM MPU, donc je voulais simplement en acheter un (en choisir un avec une documentation plus ouverte). J'ai été surpris quand j'ai découvert que même les cartes avec vraiment assez de mémoire n'avaient pas de MPU avec Memory Management Unit.

Comme j'ai toujours travaillé avec des processeurs i386 + et jamais rien d'autre (sauf pour certains PIC Microchip), je suis maintenant confus et je ne sais pas si on peut écrire un système d'exploitation fonctionnel dont les fonctionnalités ne seraient pas limitées en comparaison avec les OS écrits pour les MPU avec MMU.

Je pourrais penser à quelques solutions pour "remplacer" ou "simuler" MMU et j'ai quelques questions:

  • Sur les processeurs Intel en modes 16 et 32 ​​bits, il existe un moyen d'utiliser des segments et des sélecteurs de segments pour utiliser différents blocs de mémoire pour différentes tâches. Cela signifie que je pouvais changer l'espace mémoire en modifiant le contenu des registres de segments lors d'un changement de tâche sur x86. Existe-t-il des concepts généraux de segmentation de la mémoire qui pourraient être utilisés sur l'architecture ARM?
  • En chargeant un fichier objet lié au lieu d'exécutable, je pouvais utiliser des relocalisations (corrections) ou positionner du code indépendant pour pointer des tâches sur des morceaux de mémoire de la même manière que si j'avais mappé la mémoire à l'aide de structures de pagination. Serait-ce assez efficace?
  • J'ai également lu quelque chose sur les unités de protection de la mémoire sur les processeurs ARM. Ces informations pourraient-elles être utiles?

Existe-t-il des moyens "habituels" de gérer les tâches sur des systèmes sans MMU?

user35443
la source

Réponses:

16

En fait, il n'est pas si difficile de concevoir un système d'exploitation qui ne nécessite pas de MMU. Il y a quelques commodités dont vous devrez vous passer, mais rien d'insurmontable.

  • Étant donné que différentes tâches devront être chargées à différentes adresses, tout votre code (à l'exception du noyau, de la bibliothèque standard et de tout autre code faisant partie de votre environnement d'exécution de base) doit être compilé comme indépendant de la position. Cela signifie des sauts relatifs et une adresse de base pour l'accès au tas stockée dans un registre. Dépenser un registre comme adresse de base peut sembler coûteux si vous êtes habitué aux quatre registres généraux de x86-32, mais la plupart des architectures modernes en ont plus, et même 8088 a les registres de segments précisément pour cela.
  • Une architecture de type Unix doit être révisée, car vous ne pouvez pas l'implémenter fork. C'est ok, la plupart des systèmes d'exploitation n'en ont pas fork. (Vous pouvez avoir vfork.)
  • Vous ne pouvez pas préallouer de grandes quantités d'espace sans allouer également la mémoire correspondante. Cela signifie pas de croissance de la pile ou du tas à la volée en allouant une page de plus à la fois.

Si vous avez un MPU, vos tâches peuvent toujours être séparées les unes des autres comme d'habitude dans les systèmes d'exploitation multitâche. Sans MPU, la séparation de la mémoire ne peut être coopérative que si vous autorisez les tâches à exécuter du code arbitraire. Une façon de réaliser la séparation de la mémoire sans MPU consiste à restreindre les tâches à utiliser uniquement du code vérifié sur une machine virtuelle et à implémenter la protection de la mémoire dans le logiciel dans le cadre du moteur VM.

uClinux est un projet basé sur le noyau Linux qui fonctionne sur des processeurs (y compris ARM Cortex-M) sans MMU. Ses restrictions sur le multitâche sont essentiellement ce que j'ai décrit ci-dessus.

Gilles 'SO- arrête d'être méchant'
la source