Как получить доступ к управляющим регистрам cr0,cr2,cr3 из программы? Получение ошибки сегментации
Я написал программу, которая пытается читать и записывать в регистры управления.
Программа компилируется нормально, но когда собирается выполнить встроенную сборку, возникает ошибка сегментации.
Код:
void instructions(int val)
{
int i;
int value;
for(i = 0; i < val; i++)
__asm__("mov %cr0, %eax");
}
Я использовал GDB и прошел через каждую сборочную линию, и это на mov %cr0,%eax
что происходит ошибка сегментации.
Кто-нибудь знает, что не так?
1 ответ
Цитирование из Intel® 64 и IA-32 Архитектура Руководства разработчика программного обеспечения 3-650 Том. 2А при переходе в регистры управления и из них:
Эта инструкция может быть выполнена только тогда, когда текущий уровень привилегий равен 0.
Это означает, что инструкция может быть выполнена только в режиме ядра.
Минимальный модуль ядра, который регистрирует содержимое cr0, cr2 и cr3, может выглядеть примерно так (32-битный путь кода не проверен):
/* 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