Je pense que la solution la plus simple serait de créer un périphérique de caractères dans votre pilote de noyau, avec vos propres opérations de fichier pour un fichier virtuel. Ensuite, l'espace utilisateur peut ouvrir cet appareil O_RDWR
. Vous devez implémenter deux opérations principales sur les fichiers :
-
read
-- c'est ainsi que le noyau transmet les données à l'espace utilisateur. Cette fonction est exécutée dans le contexte du thread de l'espace utilisateur appelant leread()
appel système, et dans votre cas, il devrait bloquer jusqu'à ce que le noyau ait une autre valeur de départ dont il a besoin de connaître la sortie. -
write
-- c'est ainsi que l'espace utilisateur transmet les données au noyau. Dans votre cas, le noyau prendrait simplement la réponse à la lecture précédente et la transmettrait au matériel.
Ensuite, vous vous retrouvez avec une simple boucle dans l'espace utilisateur :
while (1) {
read(fd, buf, sizeof buf);
calculate_output(buf, output);
write(fd, output, sizeof output);
}
et aucune boucle du tout dans le noyau - tout s'exécute dans le contexte du processus de l'espace utilisateur qui pilote les choses, et le pilote du noyau est juste responsable du déplacement des données vers/depuis le matériel.
Selon ce que vous "faites des trucs aléatoires ici" du côté du noyau, il ne sera peut-être pas possible de le faire aussi simplement. Si vous avez vraiment besoin de la boucle du noyau, vous devez créer un thread du noyau pour exécuter cette boucle, puis avoir des variables du type input_data
, input_ready
, output_data
et output_ready
, ainsi que quelques files d'attente et le verrouillage dont vous avez besoin.
Lorsque le thread du noyau lit les données, vous placez les données dans input_ready
et définissez le input_ready
marquer et signaler la file d'attente d'entrée, puis faire wait_event(<output_ready is set>)
. Le read
l'opération de fichier ferait un wait_event(<input_ready is set>)
et renvoyer les données dans l'espace utilisateur lorsqu'elles sont prêtes. De même le write
l'opération de fichier mettrait les données qu'il obtient de l'espace utilisateur dans output_data
et définissez output_ready
et signaler la file d'attente de sortie.
Une autre façon (plus laide, moins portable) est d'utiliser quelque chose comme ioperm
, iopl
ou /dev/port
pour tout faire complètement dans l'espace utilisateur, y compris l'accès matériel de bas niveau.