2011-09-14 19 views
7

He escrito un programa que intenta leer y escribir en los registros de control.¿Cómo acceder a los registros de control cr0, cr2, cr3 desde un programa? Obtención de fallo de segmentación

El programa compila bien, pero cuando el ensamblaje en línea está a punto de ejecutarse, produce un error de segmentación.

Código:

void instructions(int val) 
{ 
    int i; 
    int value; 
    for(i = 0; i < val; i++) 
     __asm__("mov %cr0, %eax"); 
} 

Solía ​​BGF y di un paso a través de cada línea de montaje y que está en la mov %cr0,%eax que se produce el fallo de segmentación.

¿Alguien que sabe lo que está mal?

+0

¿Está usted en Linux? –

+0

@CiroSantilli 视 iro iro 视 视 视 ¿Te das cuenta de que esta pregunta tiene 4 años? Chris no se ha visto desde 2011. –

+0

@DavidWohlferd Sí. Tal vez algún día él regrese. No estoy esperando que él responda. Las preguntas sobre SO son útiles para siempre. A menudo respondo esos, y algunas veces tengo rep. :-) –

Respuesta

14

Citando Intel® 64 and IA-32 Architectures Software Developer Manuals 3-650 Vol. 2A en movimiento desde y hacia los registros de control:

Esta instrucción puede ser ejecutada sólo cuando el nivel de privilegio actual es 0.

Lo que significa que la instrucción sólo se puede ejecutar en modo kernel

Un módulo del núcleo mínimo, que registra el contenido de cr0, CR2 y CR3 podría ser algo como esto (ruta de código de 32 bits no probado):

/* hello.c */ 
#include <linux/module.h> 
#include <linux/kernel.h> 

int init_module(void) 
{ 
#ifdef __x86_64__ 
    u64 cr0, cr2, cr3; 
    __asm__ __volatile__ (
     "mov %%cr0, %%rax\n\t" 
     "mov %%eax, %0\n\t" 
     "mov %%cr2, %%rax\n\t" 
     "mov %%eax, %1\n\t" 
     "mov %%cr3, %%rax\n\t" 
     "mov %%eax, %2\n\t" 
    : "=m" (cr0), "=m" (cr2), "=m" (cr3) 
    : /* no input */ 
    : "%rax" 
    ); 
#elif defined(__i386__) 
    u32 cr0, cr2, cr3; 
    __asm__ __volatile__ (
     "mov %%cr0, %%eax\n\t" 
     "mov %%eax, %0\n\t" 
     "mov %%cr2, %%eax\n\t" 
     "mov %%eax, %1\n\t" 
     "mov %%cr3, %%eax\n\t" 
     "mov %%eax, %2\n\t" 
    : "=m" (cr0), "=m" (cr2), "=m" (cr3) 
    : /* no input */ 
    : "%eax" 
    ); 
#endif 
    printk(KERN_INFO "cr0 = 0x%8.8X\n", cr0); 
    printk(KERN_INFO "cr2 = 0x%8.8X\n", cr2); 
    printk(KERN_INFO "cr3 = 0x%8.8X\n", cr3); 
    return 0; 
} 

void cleanup_module(void) 
{ 
} 

 

# Makefile 

obj-m += hello.o 

all: 
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 

clean: 
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 

test: all 
    sudo insmod ./hello.ko 
    sudo rmmod hello 
    dmesg | tail 
+0

¿Querías 'u64'? Al menos 'cr3' está documentado en los manuales de intel para intel 64 de los bits 0: 63. – corny

+0

@corny: Fue solo un ejemplo rápido para mostrar cómo acceder a los registros de control, así que para simplificar, solo imprimo los 32 bits inferiores incluso en el modo de 64 bits. Creo que todos los registros de control son de 64 bits en modo largo y definitivamente quieres todos los bits de CR2/CR3 si realmente estás haciendo algo útil con los contenidos. – user786653

+0

Correcto, en el modo de 64 bits, todos los registros de control son de 64 bits. Sección 2.5, "REGISTROS DE CONTROL" en el Manual del desarrollador de software Intel® 64 e IA-32 Architectures, Volumen 3A. Edité tu respuesta, borremos nuestro comentario y preservemos tu respuesta mejorada. – corny

Cuestiones relacionadas