Previous Up Next

2  Protection de la mémoire

Accès mémoire illégal

Vous avez tous expérimenté le fait que dans un processus Unix, une tentative d’accès à l’adresse 0 provoque l’apparition d’un message de type segmentation fault. Ce message signifie que le processus courant a tenté d’accéder à une adresse mémoire à laquelle il n’a pas légitimement accès ; ce peut être l’adresse 0 ou une autre adresse.

Si l’accès à un pointeur nul génère une erreur de segmentation, ce n’est pas parce que le programme est incorrect mais parce qu’il tente d’accéder à une zone de la mémoire que le système d’exploitation ne lui a pas confié. Ainsi, le noyau d’un système d’exploitation peut (et est parfois amené à) écrire à l’adresse 0 de la mémoire physique, et le compilateur C n’interdit pas, a priori, cette opération.


Exercice 1
 (Accès illégal ?)  
Question 1   Décrivez le comportement du programme suivant :
static void 
mmuhandler() 
{
    printf("tentative d’accès illégal à l’adresse %p\n", 
           _in(MMU_FAULT_ADDR));
}

int 
main(int argc, char **argv) 
{
    char *ptr;

    ... /* init_hardware() */
    IRQVECTOR[MMU_IRQ] = mmuhandler;
    _mask(1);

    ptr = (char*)0;
    *ptr = 'c';
}
Question 2   Proposez une correction du programme précédent de telle sorte qu’il se comporte correctement lorsqu’une erreur d’accès à la mémoire se produit.

Modes maître et utilisateur

Le mode maître et le mode utilisateur sont deux états de fonctionnement possibles des microprocesseurs permettant l’isolation des fautes et de la mémoire entre différents processus.

En mode maître, seule la mémoire physique est accessible, alors qu’en mode utilisateur c’est la mémoire virtuelle qui est accessible. Le début de la mémoire physique est occupé par le vecteur d’interruption (que nous utilisons sous le nom de variable IRQVECTOR).

Après l’initialisation du matériel réalisée par la fonction init_hardware(), le microprocesseur est en mode maître.

À chaque fois qu’une interruption est appelée, le microprocesseur exécute le code de l’interruption en mode maître.

Le bit 12 du registre de masque indique si le microprocesseur est en mode maître ou utilisateur. La valeur 0 est associée au mode maître, la valeur 1 au mode utilisateur.

À titre d’exemple, l’appel suivant

_mask(0x1001);

Exercice 2
 (Passage en mode utilisateur!)  
Question 1   Quel est le comportement du programme ci-dessous ?
static void 
mmuhandler() 
{
    printf("tentative d’accès illégal à l’adresse %p\n", 
            _in(MMU_FAULT_ADDR));
}

int 
main(int argc, char **argv) 
{
    ... /* init_hardware() */
    IRQVECTOR[MMU_IRQ] = mmuhandler;
    _mask(0x1001);
    IRQVECTOR[MMU_IRQ] = mmuhandler;
}
Question 2   Quelles sont les valeurs possibles de ADDRESS qui mènent à terminaison sur un succès ?
#define ADDRESS  ...

static void 
mmuhandler() 
{
    printf("tentative d’accès illégal à l’adresse %p\n", 
            _in(MMU_FAULT_ADDRESS));
    exit(EXIT_FAILURE);
}

int 
main(int argc, char **argv) 
{
    char *ptr; 

    ... /* init_hardware() */
    IRQVECTOR[MMU_IRQ] = mmuhandler;
    _mask(0x1001);

    ptr = ADDRESS; 
    *ptr = 'c'; 

    exit(EXIT_SUCCESS);
}

Previous Up Next