#c #linux #memory #assembly #kernel
#c #linux #память #сборка #ядро
Вопрос:
Я пытаюсь добавить запись в MTRR, чтобы пометить область памяти как объединенную для записи, но ядро не принимает мой вызов. Он возвращает ошибку EINVAL errno. В чем может быть проблема? Я перепробовал все, но безуспешно. Вот код и результат после его запуска:
#define NUM_ELTS (1024*64)
struct mtrr_sentry sentry;
void register_wc(uint *addr);
void register_wc(uint *addr) {
int fd,ret;
int aux1,aux2;
int page_size;
sentry.base=(ulong) addr;
sentry.size=NUM_ELTS;
sentry.type=MTRR_TYPE_WRCOMB;
page_size=getpagesize();
aux1=sentry.base amp; (page_size - 1);
aux2=sentry.size amp; (page_size - 1);
printf("aux1=%d, aux2=%d, base=%d, size=%d, type=%dn",aux1,aux2,sentry.base,sentry.size,sentry.type);
fd=open("/proc/mtrr",O_WRONLY); if (fd==-1) { perror("open()"); exit(2); }
printf("fd=%dn",fd);
ret=ioctl(fd,MTRRIOC_ADD_ENTRY,amp;sentry); if (ret==-1) { perror("ioctl()"); exit(3); }
sleep(10);
close(fd);
}
int main(int argc, char **argv) {
ulong size;
uint *data;
size=sizeof(uint)*NUM_ELTS;
data=(uint*) memalign(4096,size); if (!data) { exit(1); }
printf("data address is %d, PAGE_SIZE=%dn",data,getpagesize());
register_wc(data);
}
Результат, созданный программой, является:
data address is -1420279808, PAGE_SIZE=4096
aux1=0, aux2=0, base=-1420279808, size=65536, type=1
fd=3
ioctl(): Invalid argument
Код скопирован (почти) из /usr/src/linux/Documentation/x86/mtrr.txt
Ответ №1:
Базовый адрес, на который вы передаете MTRRIOC_ADD_ENTRY
, должен быть физическим адресом. Похоже, что вы передаете логический адрес только что выделенному блоку памяти, что не имеет никакого смысла. MTRR используются для управления доступом к оборудованию с отображением памяти, а не к оперативной памяти.
Комментарии:
1. тогда как мне преобразовать логический адрес, возвращаемый из memalign() в функции main(), в физический адрес?
2. Вы не можете. У него нет фиксированного физического адреса. В любом случае память, возвращаемая с помощью
memalign()
, не является памятью устройства, поэтому включение объединения записи действительно не имеет смысла.3. Вы хотите сказать, что драйвер MTRR в ядре Linux бесполезен? Тогда как вы помечаете блок памяти как объединение записи? Я мог бы сделать это, записывая непосредственно в процессор, но я видел, что в ядре Linux есть api для этого, но, по-видимому, он работает плохо, или я не знаю, как его использовать.
4. Как говорится в README, и, как я уже говорил ранее, это для управления доступом к памяти устройства, например, к видеокартам. Далеко не бесполезно, просто бесполезно для вас .
5. то, что видеокарты используют это, не означает, что память WC предназначена только для устройств. Вы можете ускорить работу своего приложения в 7 раз, если используете WC, все эти инструкции MOVNTQA будут работать так, как они были разработаны для работы, т.Е. Не загрязняя кэш.
Ответ №2:
Что сказал @duskwulf.
Вы не определили
struct mtrr_sentry sentry
и у участников нет адресов.
РЕДАКТИРОВАТЬ: я думаю, вы хотите добавить определение mtrr_sentry .
#include <asm/mtrr.h>
Комментарии:
1. да, я это сделал, я просто не включил заголовок, потому что у webiste возникают проблемы при вставке символа ‘#’