Se connecter

Informatique

Programmation

Sujet : [Baremetal] Lancer 2 OS
1
neytsumi
Niveau 12
04 mai 2021 à 19:13:15

Salut, je travaille sur un mini OS baremetal pour Raspbery Pi et je dois étudier la possibilité de lancer 2 instances de l'OS sur 2 coeurs différents (un OS par coeur).

Je sais que je demande quelque chose de vraiment particulier :hap: mais si je peux avoir des pistes je prends :oui:

Je veux qu'il y ait vraiment une copie du code de l'OS pour chaque coeur.
Au début je pensais que c'était faisable avec un linker script mais il ne veut pas de section dupliquée :(

Actuellement j'ai deux "pistes" :

  • compiler l'OS pour le premier coeur (i.e. qu'il ait son propre espace d'adressage) et faire de même pour le second coeur en modifiant juste les adresses de chaque section. Puis "fusionner" les deux fichiers générés. Mais je sais pas trop comment, coller les deux ELF est-il possible ? Ou alors avec objcopy y'a peut-être moyen de bidouiller directement le binaire brut.
  • l'autre idée c'est de travailler avec de la mémoire virtuelle, malheureusement je découvre un peu le fonctionnement, est-ce c'est possible de faire le mapping adresse virtuelle -> adresse physique en fonction du coeur ?

Dans l'idée je veux un truc similaire à Barrelfish pour ceux qui connaissent.
http://www.barrelfish.org/

J'ai essayé de voir un peu leur code mais c'est assez compliqué et sûrement un peu overkill pour mon besoin particulier.

Donc voilà si vous avez des idées ou des questions je suis preneur :hap: Merci !

neytsumi
Niveau 12
05 mai 2021 à 10:38:15

Personne n'a d'idées ? :snif:

godrik
Niveau 22
05 mai 2021 à 21:10:37

Salut a toi neytsumi,

Je ne susi jamais descendu si bas dans la gestion des systemes d'exploitation. Mais voici quelques idee.

Fondamentallement, il n'y a pas de raison que l'on ne puisse passe faire tourner un noyau different sur chacun des coeurs. En supposant que les deux noyaux fonctionne sur des plages d'addresse physique differente, la question de l'addressage physique devrait etre regler. Ensuite les processus qui vont tourner sur chacun des OS aura ses addresses virutelles mappe a des addresses physique differente par le kernel local. Donc l'addressage de la RAM ne devrait pas poser probleme.

Le probleme principal que je vois est la gestion des peripheriques. Ces trucs la fonctionne principalement par interruption. Et la question de comment router les interruptions aux different kernel ne me parait pas trivial. Clairement il va falloir une genre de couche d'abstraction pour faire ca. Et je en sais pas si c'est une fonctionalite native.

_lucco_
Niveau 10
07 mai 2021 à 18:20:20

Par curiosité tu fais ça pourquoi ? Car ça a l'air d'être un taf monstrueux :hap:

arkalys
Niveau 7
09 mai 2021 à 18:01:46

Fondamentallement, il n'y a pas de raison que l'on ne puisse passe faire tourner un noyau different sur chacun des coeurs. En supposant que les deux noyaux fonctionne sur des plages d'addresse physique differente, la question de l'addressage physique devrait etre regler. Ensuite les processus qui vont tourner sur chacun des OS aura ses addresses virutelles mappe a des addresses physique differente par le kernel local. Donc l'addressage de la RAM ne devrait pas poser probleme.

Je suis clairement un gros noob en système mais pourquoi les deux cores auraient un accès mémoire séparé ? Ils sont sur le même socket et ont donc le même bus qui les connectent aux chips DRAM. Deja qu’ils partagent le même L3. Si c’était un multisocket ça aurait pu le faire en supposant que les diffèrents sockets appartiennent a des nodes NUMA differents. Et encore, il faudrait s’assurer que les accès mémoire cross nodes via l’inter connect ne se fassent pas.

Je peux pas trop t’aider l’auteur désolé. Si ça avait la été bare metal, un hypervisor qui supporte le cpu pinning aurait au moins fixé le problème de core.

neytsumi
Niveau 12
16 mai 2021 à 17:00:56

Le 05 mai 2021 à 21:10:37 :
Salut a toi neytsumi,

Je ne susi jamais descendu si bas dans la gestion des systemes d'exploitation. Mais voici quelques idee.

Fondamentallement, il n'y a pas de raison que l'on ne puisse passe faire tourner un noyau different sur chacun des coeurs. En supposant que les deux noyaux fonctionne sur des plages d'addresse physique differente, la question de l'addressage physique devrait etre regler. Ensuite les processus qui vont tourner sur chacun des OS aura ses addresses virutelles mappe a des addresses physique differente par le kernel local. Donc l'addressage de la RAM ne devrait pas poser probleme.

Le probleme principal que je vois est la gestion des peripheriques. Ces trucs la fonctionne principalement par interruption. Et la question de comment router les interruptions aux different kernel ne me parait pas trivial. Clairement il va falloir une genre de couche d'abstraction pour faire ca. Et je en sais pas si c'est une fonctionalite native.

Merci pour ta réponse :oui:

C’est vrai que j’aurai probablement des soucis au niveau des drivers et du dispatching des interruptions :(

Mais avant d’en arriver là tu aurais une idée de la manière à faire pour arriver à compiler un tel OS ? Pour le moment c’est sûr ça que je bloque :hap:

neytsumi
Niveau 12
16 mai 2021 à 17:11:45

Le 07 mai 2021 à 18:20:20 :
Par curiosité tu fais ça pourquoi ? Car ça a l'air d'être un taf monstrueux :hap:

J’étudie de nouvelles approches pour faire du multicoeur en système temps réel :hap:

Le 09 mai 2021 à 18:01:46 :

Fondamentallement, il n'y a pas de raison que l'on ne puisse passe faire tourner un noyau different sur chacun des coeurs. En supposant que les deux noyaux fonctionne sur des plages d'addresse physique differente, la question de l'addressage physique devrait etre regler. Ensuite les processus qui vont tourner sur chacun des OS aura ses addresses virutelles mappe a des addresses physique differente par le kernel local. Donc l'addressage de la RAM ne devrait pas poser probleme.

Je suis clairement un gros noob en système mais pourquoi les deux cores auraient un accès mémoire séparé ? Ils sont sur le même socket et ont donc le même bus qui les connectent aux chips DRAM. Deja qu’ils partagent le même L3. Si c’était un multisocket ça aurait pu le faire en supposant que les diffèrents sockets appartiennent a des nodes NUMA differents. Et encore, il faudrait s’assurer que les accès mémoire cross nodes via l’inter connect ne se fassent pas.

Je peux pas trop t’aider l’auteur désolé. Si ça avait la été bare metal, un hypervisor qui supporte le cpu pinning aurait au moins fixé le problème de core.

Tout passe par le même bus de données et d’adresses en effet, ce qui compte c’est que les cœurs se répartissent la mémoire, c’est à dire que si j’ai 1024 octets de RAM et 2 cœurs, en gros je veux que le premier cœur fonctionne sur les 512 premiers octets et le deuxième sur les 512 autres :oui:

AtmelAVR
Niveau 4
16 mai 2021 à 17:15:48

Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

neytsumi
Niveau 12
16 mai 2021 à 17:19:54

Le 16 mai 2021 à 17:15:48 :
Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

Merci pour ta réponse :oui:

En effet c’est possible de lancer tous les cœurs sur le noyau mais c’est pas ce que je veux :hap: je veux vraiment qu’il y ait une image par cœur séparée, que chaque cœur soit indépendant (même si le code est dupliqué). Y’a que quelques sections de paramétrage de la MMU ou des timers que je dois faire que sur un seul cœur

AtmelAVR
Niveau 4
16 mai 2021 à 17:24:06

Le 16 mai 2021 à 17:19:54 :

Le 16 mai 2021 à 17:15:48 :
Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

Merci pour ta réponse :oui:

En effet c’est possible de lancer tous les cœurs sur le noyau mais c’est pas ce que je veux :hap: je veux vraiment qu’il y ait une image par cœur séparée, que chaque cœur soit indépendant (même si le code est dupliqué).

Je comprends pas trop l’intérêt. Le bootloader va charger ton noyau à une certaine adresse et ensuite chaque cœur va commencer à exécuter le code à cette adresse. Donc à ce moment en mémoire physique il n'y a qu'une image du noyau. Pourquoi tu veux la dupliquer pour chaque cœur ? T'as l'intention de modifier le noyau pendant l'exécution ou quoi ? :(
Après tu peux toujours dupliquer le noyau à un autre endroit en mémoire physique pour chaque cœur si tu le souhaite vraiment, mais je vois pas bien à quoi ça sert.

neytsumi
Niveau 12
16 mai 2021 à 17:27:21

Le 16 mai 2021 à 17:24:06 :

Le 16 mai 2021 à 17:19:54 :

Le 16 mai 2021 à 17:15:48 :
Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

Merci pour ta réponse :oui:

En effet c’est possible de lancer tous les cœurs sur le noyau mais c’est pas ce que je veux :hap: je veux vraiment qu’il y ait une image par cœur séparée, que chaque cœur soit indépendant (même si le code est dupliqué).

Je comprends pas trop l’intérêt. Le bootloader va charger ton noyau à une certaines adresse et ensuite chaque cœur va commencer à exécuter le code à cette adresse. Donc à ce moment en mémoire physique il n'y a qu'une image du noyau. Pourquoi tu veux la dupliquer pour chaque cœur ? T'as l'intention de modifier le noyau pendant l'exécution ou quoi ? :(
Après tu peux toujours dupliquer le noyau à un autre endroit en mémoire physique pour chaque cœur si tu le souhaite vraiment, mais je vois pas bien à quoi ça sert.

Je travaille sur des systèmes temps réel et une des problématiques du multicoeur dans ces systèmes c’est les latences induites par les accès concurrents au même adresses, que ce soit en mémoire ou dans le cache. On me demande de tester une approche où chaque cœur est indépendant de manière à limiter les accès concurrents. J’utilise aussi de la coloration de cache pour « réserver » certaines lignes de caches aux parties critiques.

AtmelAVR
Niveau 4
16 mai 2021 à 17:32:06

Le 16 mai 2021 à 17:27:21 :

Le 16 mai 2021 à 17:24:06 :

Le 16 mai 2021 à 17:19:54 :

Le 16 mai 2021 à 17:15:48 :
Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

Merci pour ta réponse :oui:

En effet c’est possible de lancer tous les cœurs sur le noyau mais c’est pas ce que je veux :hap: je veux vraiment qu’il y ait une image par cœur séparée, que chaque cœur soit indépendant (même si le code est dupliqué).

Je comprends pas trop l’intérêt. Le bootloader va charger ton noyau à une certaines adresse et ensuite chaque cœur va commencer à exécuter le code à cette adresse. Donc à ce moment en mémoire physique il n'y a qu'une image du noyau. Pourquoi tu veux la dupliquer pour chaque cœur ? T'as l'intention de modifier le noyau pendant l'exécution ou quoi ? :(
Après tu peux toujours dupliquer le noyau à un autre endroit en mémoire physique pour chaque cœur si tu le souhaite vraiment, mais je vois pas bien à quoi ça sert.

Je travaille sur des systèmes temps réel et une des problématiques du multicoeur dans ces systèmes c’est les latences induites par les accès concurrents au même adresses, que ce soit en mémoire ou dans le cache. On me demande de tester une approche où chaque cœur est indépendant de manière à limiter les accès concurrents. J’utilise aussi de la coloration de cache pour « réserver » certaines lignes de caches aux parties critiques.

D'accord, je comprends mieux. Dans ce cas tu peux dupliquer l'image du noyau ailleurs pour chaque cœur et sauter vers cette adresse. Si tu compiles ton code en PIC (position independent code) tu devrais pas avoir de problème. Mais si de toute façon tu comptes utiliser la MMU sur chaque cœur, t'as qu'à mapper l’adresse physique du noyau correspondant au cœur local vers l'adresse où il est sensé être et ça devrait être bon.

neytsumi
Niveau 12
16 mai 2021 à 17:37:08

Le 16 mai 2021 à 17:32:06 :

Le 16 mai 2021 à 17:27:21 :

Le 16 mai 2021 à 17:24:06 :

Le 16 mai 2021 à 17:19:54 :

Le 16 mai 2021 à 17:15:48 :
Normalement tous les cœurs commencent à exécuter le noyaux sans que t'ai besoin d'avoir une image du noyaux par cœur ou quoi que ce soit de spécial. Sur certains systèmes t'as parfois qu'un cœur qui démarre et il faut ensuite "réveiller" les autres manuellement, mais sur un Raspberry Pi tous les cœurs démarrent en même temps. Ensuite tu peux aller voir le cpuid pour savoir sur quel cœur tu es faire ce que tu veux en conséquence. Pour la mémoire virtuelle, le mapping est local à chaque cœur.

Merci pour ta réponse :oui:

En effet c’est possible de lancer tous les cœurs sur le noyau mais c’est pas ce que je veux :hap: je veux vraiment qu’il y ait une image par cœur séparée, que chaque cœur soit indépendant (même si le code est dupliqué).

Je comprends pas trop l’intérêt. Le bootloader va charger ton noyau à une certaines adresse et ensuite chaque cœur va commencer à exécuter le code à cette adresse. Donc à ce moment en mémoire physique il n'y a qu'une image du noyau. Pourquoi tu veux la dupliquer pour chaque cœur ? T'as l'intention de modifier le noyau pendant l'exécution ou quoi ? :(
Après tu peux toujours dupliquer le noyau à un autre endroit en mémoire physique pour chaque cœur si tu le souhaite vraiment, mais je vois pas bien à quoi ça sert.

Je travaille sur des systèmes temps réel et une des problématiques du multicoeur dans ces systèmes c’est les latences induites par les accès concurrents au même adresses, que ce soit en mémoire ou dans le cache. On me demande de tester une approche où chaque cœur est indépendant de manière à limiter les accès concurrents. J’utilise aussi de la coloration de cache pour « réserver » certaines lignes de caches aux parties critiques.

D'accord, je comprends mieux. Dans ce cas tu peux dupliquer l'image du noyau ailleurs pour chaque cœur et sauter vers cette adresse. Si tu compiles ton code en PIC (position independent code) tu devrais pas avoir de problème. Mais si de toute façon tu comptes utiliser la MMU sur chaque cœur, t'as qu'à mapper l’adresse physique du noyau correspondant au cœur local vers l'adresse où il est sensé être et ça devrait être bon.

Si j’ai bien compris j’ai qu’un seul noyau et ensuite pour chaque cœur je vais faire le mapping vers leur espace RAM réservé ?

1
Sujet : [Baremetal] Lancer 2 OS
   Retour haut de page
Consulter la version web de cette page