7
votes

Changer la table descripteur d'interruption

J'utilise la version du noyau Linux 2.6.26 et j'essaie de modifier la table descripteur d'interruption à l'aide d'un module de noyau. J'essaie seulement de changer l'entrée de la table de défaut de page ici. Donc, je fais une copie de l'IDT d'origine et apporte des modifications à l'entrée de la table de défaut de page uniquement. L'objectif de l'ISR est d'imprimer des informations sur la défaillance de la page avant d'appeler le gestionnaire de défaut de page d'origine. Mais le noyau se bloque une fois que je l'charge avec insmod, il s'est spécifiquement écrasé avec la fonction "LOADIDTR". Avec un débogage supplémentaire, j'ai découvert que, en modifiant aucune entrée si je charge l'IDTR, cela fonctionne bien. Je suis à court d'idées.

J'ai collé le code ci-dessous xxx


2 commentaires

Voir aussi Stackoverflow.com/questions/5302392 - et la réponse d'Amrzar ci-dessous. Le noyau fournit déjà des fonctions utilitaires pour remplacer des entrées spécifiques dans les tables de descripteur et / ou dans les tableaux entières. Le piratage de bas niveau autour de cela est rarement une bonne idée.


Pourquoi quand j'utilise Imprimer dans ma fonction C, le système génère un défaut SEG ??


3 Réponses :


2
votes

Votre sélecteur de segment dans votre descripteur de porte d'interruption semble être codé dur sur 0x0010 , quand il devrait être __ kernel_cs (qui est 0x0060 dans le 2.6.26 Sources de noyau que j'ai).

Au fait, c'est assez baroque: xxx

Vous pouvez simplifier cela (avec le correctif __kernel_cs): < / p> xxx


2 commentaires

Votre droit à ce sujet .. Merci ... mais le code s'écrase dans la fonction My_Intropt. Je ne suis pas sûr de suivre une question ici ...


Pourquoi quand j'utilise Imprimer dans ma fonction C, le système génère un défaut SEG ??



7
votes

Pourquoi n'utilisez-vous pas la fonction de noyau au lieu de violer manuellement des bits! Vérifiez-le (c'est le module d'initialisation Func):

struct desc_ptr newidtr;
gate_desc *oldidt, *newidt;

store_idt(&__IDT_register);
oldidt = (gate_desc *)__IDT_register.address;

__IDT_page =__get_free_page(GFP_KERNEL);
if(!__IDT_page)
    return -1;

newidtr.address = __IDT_page;
newidtr.size = __IDT_register.size;
newidt = (gate_desc *)newidtr.address;

memcpy(newidt, oldidt, __IDT_register.size);

pack_gate(&newidt[PGFAULT_NR], GATE_INTERRUPT, (unsigned long)isr0x0E, 0, 0, __KERNEL_CS);

__load_idt((void *)&newidtr);
smp_call_function(__load_idt, &newidtr, 0, 1);

return 0;


0 commentaires

0
votes

Pour référence, voici une implémentation de fonctionnement d'un gestionnaire de défaut de page personnalisé pour l'architecture Linux X86_64. Je viens de tester ce module moi-même avec le noyau 3.2, ça marche parfaitement.

https://github.com/Richardustc/intercept-page-fault-handler < / a>


0 commentaires