2010-08-05 32 views
2

Je cherche des informations concernant l'implémentation de certaines extensions CPU dans un module noyau. J'ai trouvé quelque chose en rapport: http://www.mirrors.docunext.com/lxr/http/source/arch/mips/kernel/unaligned.c en fait, c'est le seul code source que je peux trouver qui est même proche. Fondamentalement, je n'ai qu'un objet partagé binaire construit avec certaines extensions CPU, dont j'ai besoin pour fonctionner sur un processeur un peu plus ancien qui a la plupart des instructions définies, mais pas les nouvelles fonctionnalités. Oui, je sais que ça va être plutôt lent, mais c'est mieux que de s'écraser avec SIGILLs.Implémentation d'extensions de CPU dans un module noyau

+0

votre lien est cassé ... – luke

+0

Shazbot! Fixe merci. – joe

+0

Je pense que votre question pourrait être un peu trop large. Vous avez déjà l'idée de base - intercepter le piège qui aboutit finalement à SIGILL, et à la place examiner l'état du processus utilisateur et émuler l'instruction qu'il a essayé d'exécuter. (Je ne pense pas que vous serez capable de le faire à partir d'un module - il faudra probablement le compiler, sauf si vous ajoutez des shims pour que le module s'y connecte). Alors, quelle est la vraie question? – caf

Répondre

1

Eh bien, après avoir lu la source du noyau, il semble qu'il y ait déjà un support mineur pour cela. Je ne peux vraiment pas voir combien il est réellement utilisé, mais il existe une liste chaînée pour stocker les différentes instructions émulées. Si je suis en mesure de le faire, je vais probablement le remplacer par l'arborescence fournie par l'en-tête du noyau.

Si je comprends bien les modules du noyau, il ne semble pas qu'il y ait un problème pour prendre en charge l'émulation enfichable.

1

Je ne pense pas que vous pouvez résoudre ce problème en utilisant un module noyau. Je pense que vous devez soit exécuter cela dans une machine virtuelle qui permet les instructions manquantes (j'essayerais d'utiliser XEN) ou recompiler l'objet afin qu'il ne les utilise pas.

+0

Je pense que @joe signifie quelque chose comme les anciennes astuces d'émulation FP utilisées sur les anciens processeurs sans unités FP. Je ne suis pas sûr que quelqu'un fasse des recherches à ce sujet maintenant. –

+0

L'unité FP externe est en fait la 2ème partie de l'image plus grande. Mais je vais jouer avec ça quand j'y viendrai. Voici un exemple x86 (le CPU cible est ARM): si le CPU n'avait pas de support pour SSE2, quand il rencontrait une instruction ADDPD, le noyau lancerait (ou quelque chose comme un filtre, selon la vitesse la plus rapide) un SIGILL interne capturé par lui-même (module kernel, ou etc.), qui appelle alors la fonction spécifique qui a implémenté ADDPD. Il ne doit pas nécessairement s'agir d'un module noyau, il se peut que le cadre du noyau soit écrit, ce qui est bien. – joe

2

Je pense que vous pouvez le faire dans userland. Installez un gestionnaire pour SIGILL avec sigaction() et spécifiez SA_SIGINFO. Le champ si_code du siginfo_t permet de distinguer plusieurs causes de SIGILL. Par exemple, essayer d'émuler une instruction lorsque le signal provient de kill() n'a pas de sens. Le troisième argument du gestionnaire pointe vers une structure contenant le contexte de la CPU au moment de l'erreur (voir la documentation). Vous pouvez probablement modifier cela et revenir du gestionnaire de signal, les changements prenant effet; Si cela ne fonctionne pas, essayez setcontext().

De toute évidence, ce sera un peu moins efficace que de le faire dans le noyau, mais plus propre et plus sûr.

2

Vous pouvez le faire, mais c'est légèrement douloureux. Les opcodes invalides doivent être interceptés, vous devez donc soit modifier le gestionnaire d'instructions illégal existant, soit envelopper le gestionnaire, ce qui est sale et compliqué.

Si vous voulez éviter les mods du noyau, mais faites comme un noyau pur, l'approche de l'exception encapsulée est probablement le seul moyen de le faire. Si vous pouvez modifier le noyau, le gestionnaire corrigé est meilleur.