2013-02-08 7 views
8

J'ai un gros système écrit principalement en C qui fonctionnait dans l'espace utilisateur jusqu'à maintenant. Maintenant, j'ai besoin de compiler le code en tant que module du noyau. Pour cela, afaik, je devrais au moins réécrire le code et remplacer les fonctions comme malloc, calloc, free, printf avec leurs équivalents noyau, car ce sont uniquement des fonctions de l'espace utilisateur. Le problème est, cependant, que je n'ai pas le code source à certaines bibliothèques sur mesure utilisées dans le système, et ces bibliothèques appellent malloc etc. dans leurs fonctions. Donc, fondamentalement, je pourrais avoir besoin de réimplémenter toute la bibliothèque.Portage du code de l'espace utilisateur vers l'espace noyau

Maintenant la question: sera-ce un hack vraiment sale, si j'écrire mon propre implémentation de malloc comme une enveloppe autour kmalloc, quelque chose comme ceci:

void *malloc(size_t size) { 
    return kmalloc(size, GFP_USER); 
} 

redirigent ensuite cette mise en œuvre du système code, qui permettra d'éliminer tous les symbole inconnu dans le module erreurs.

En fait, je pensais que ce serait un problème commun et quelqu'un aurait déjà écrit un tel wrapper kmalloc, mais je googling depuis quelques jours maintenant et n'a rien trouvé d'utile.

EDIT: La raison pour cela est que le système dont je parle était une application en temps réel fonctionnant sur le système d'exploitation en temps réel VxWorks et maintenant nous voulons le porter sur Linux RTAI, où les applications s'exécutent principalement dans le noyau espace. Mais je suppose qu'il y a une possibilité d'avoir du temps réel dans l'espace utilisateur, donc, je devrais probablement faire comme Mike a suggéré et séparer le code en parties noyau et espace utilisateur et communiquer entre eux avec de la mémoire partagée.

+0

Je viens de voir [ce hack] (http://stackoverflow.com/a/14728092/912144) pour gcc qui peut vous être utile. – Shahbaz

+9

Normalement, les gens essaient de sortir les choses du noyau, plutôt que l'inverse. Mon expérience personnelle est que si vous pensez que vous avez besoin de faire un module noyau de votre programme, alors vous le faites probablement mal. –

+0

@JoachimPileborg il est probablement arrivé à penser qu'il sera plus rapide dans l'espace noyau – Ulterior

Répondre

8

Je n'ai jamais vu cela auparavant. J'ai dû faire quelque chose de similaire à un travail précédent (dans nos téléphones, pour des raisons d'économie d'énergie, nous avons dû transférer une partie du code de l'espace utilisateur du noyau) mais c'est comme ça que je l'ai fait .. une partie du code et déplacé, et une petite partie à cela.

Quand je l'ai fait je changé l'espace utilisateur appelle à noyau appels en raison d'un certain nombre de raisons deux ones primaires:

  1. Il a été moins confus de cette façon (d'autres regardant le code n'a pas eu se demander pourquoi j'appelais "malloc" du noyau)

  2. malloc et kmalloc ne fonctionnent pas exactement la même chose. Ce que je veux dire par là, c'est

    2a. kmalloc prend un paramètre flags, dans votre exemple ci-dessus vous l'avez codé en dur. Que faire si vous décidez plus tard que vous voulez le changer dans certains endroits et pas d'autres? (En supposant que vous avez un certain nombre d'endroits différents où vous obtenez de la mémoire dynamique).

    2b. kmalloc ne vous donne pas de mémoire de la même manière que malloc. malloc() vous donnera le nombre d'octets que vous passez en tant que size_t size. D'autre part, est dans le noyau et traite donc de la mémoire physique du système, qui n'est disponible que dans les morceaux de la taille d'une page; Ainsi, lorsque vous appelez le kmalloc(), vous n'obtiendrez que certains tableaux prédéfinis d'octets de taille fixe. Si vous n'êtes pas conscient de cela, vous pouvez demander sur un morceau particulier et ainsi obtenir beaucoup plus de mémoire que vous avez besoin ... un port direct de votre code ne vous protégera pas de cela.

    2c. Les fichiers d'en-tête doivent également changer. Evidemment, vous ne pouvez pas inclure <stdlib.h> dans le noyau, donc juste parce que vous avez "enveloppé" l'appel malloc, vous devez toujours faire le tour des fichiers d'en-tête.

exemple rapide de mon point 2b ci-dessus:

void * stuff; 
stuff = kmalloc(1,GFP_KERNEL); 
printk("I got: %zu bytes of memory\n", ksize(stuff)); 
kfree(stuff); 

Pour afficher la quantité réelle de mémoire allouée:

[90144.702588] I got: 32 bytes of memory 

de toute façon ... techniquement, comment vous Décrivez-le, cela devrait fonctionner correctement. Les deux prennent un size_t et renvoient un void * pour que cela fonctionne; mais sachez que plus le code est déplacé dans le noyau, moins les choses deviennent déterministes, et malloc() < =>kmalloc() n'est pas aussi 1: 1 qu'il n'y paraît.

0

En essayant de rendre mon code RTAI compilable dans les espaces utilisateur et noyau (en plus de travailler avec POSIX), j'ai développé URT qui fait essentiellement ce que vous demandez. Il s'agit d'un niveau d'abstraction léger sur les systèmes en temps réel (et même sur les fonctions RTAI espace-utilisateur et espace-noyau incompatibles).