2014-11-09 7 views
3

Я играю с mmap и/proc/mtrr, чтобы сделать некоторый углубленный анализ анализа физической памяти. Вот основная идея того, что я пытаюсь сделать, и краткое изложение того, что я сделал до сих пор. Я нахожусь в ядре Ubuntu версии 3.5.0-54.Доступ к недоступной области с помощью mmap и/proc/mtrr

Я в основном mmapping к определенному физическому адресу (используя подсказки от/proc/iomem) и измеряя латентность доступа к этому диапазону физических адресов. Вот что я сделал до сих пор:

  1. Создал запись в/proc/mtrr, чтобы сделать диапазон физических адресов, который я буду mmapping uncachable.
  2. mmaped по конкретному адресу с использованием/dev/mem. Мне пришлось отключить ограничения безопасности, чтобы читать более 1 МБ от/dev/mem.

В то время как я могу выполнить программу без проблем, у меня есть некоторые сомнения относительно того, работает ли неотъемлемая часть. Вот фрагмент кода, который я использую. Обратите внимание, что я использовал псевдокод из предыдущей исследовательской статьи для создания этого кода.

int main(int argc, char *argv[]) { 
    int fd; // file descriptor to open /dev/mem 
    struct timespec time1, time2; 
    fd = open("/dev/mem", O_RDWR|O_SYNC); 
    if (fd == -1) { 
     printf("\n Error opening /dev/mem"); 
     return 0; 
    } 
    struct timespec t1, t2; 
    char *addr = (char*)mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0x20000); 
    if (addr == MAP_FAILED) { 
     printf("\n mmap() failed"); 
    } 
    // Begin accessing 
    char *addr1 = addr; 
    char *addr2 = addr1 + 64; // add cache line 

    unsigned int i = 0; 
    unsigned int j = 0; 
    // Begin accessing uncached region 
    while(j < 8192){ 
     i = 0; 
     while(i < 500) { 
      *addr1 = *addr2 + i; 
      *addr2 = *addr1 + i; 
      i = i+1; 
     } 
     j = j + 64; 
     addr2 = addr1 + j; 
    } 
    if (munmap(addr, 8192) == -1) { 
     printf("\n Unmapping failed"); 
     return 0; 
    } 
    printf("\n Success......"); 
    return 0; 
} 

Я использую смещение 0x20000 на основании выходного сигнала/Proc/iomem, как показано ниже (с указанием только соответствующие данные):

00000000-0000ffff : reserved 
**00010000-0009e3ff : System RAM** 
0009e400-0009ffff : RAM buffer 
000a0000-000bffff : PCI Bus 0000:00 
000a0000-000b0000 : PCI Bus 0000:20 
000c0000-000effff : PCI Bus 0000:00 

Ниже приведены данные в/Proc/MTRR:

reg00: base=0x0d3f00000 (3391MB), size= 1MB, count=1: uncachable 
reg01: base=0x0d4000000 (3392MB), size= 64MB, count=1: uncachable 
reg02: base=0x0d8000000 (3456MB), size= 128MB, count=1: uncachable 
reg03: base=0x0e0000000 (3584MB), size= 512MB, count=1: uncachable 
reg04: base=0x000020000 ( 0MB), size= 8KB, count=1: uncachable 

Как вы можете видеть, конечная запись делает область нежелательного адреса непригодной.

В то время как у меня нет никаких проблем с запуском кода, у меня есть следующие проблемы:

  1. Правильно ли выбрать этот конкретный физический адрес диапазона обозначаемая System RAM, чтобы сделать чтение/запись? Я понимаю, что этот диапазон адресов используется для хранения данных и кода. Кроме чтения/dev/mem с помощью hexdump, я заметил, что область адресов неинициализирована (установлена ​​в 0).
  2. Чтобы проверить, действительно ли доступ к незашифрованной области фактически не закрыт, я выполняю первичную статистику кеша-кешей: u для измерения количества промахов в кеше. Я получаю номер в диапазоне 128 200. Для меня это подтверждает, что адреса не кэшируются и поступают в ОЗУ, как в цикле, я делаю (8192/64) * 500 * 2 = 128 000 обращений. Я выполнил одно и то же упражнение с другим подобным фрагментом кода с заменой mmap на динамическое выделение памяти массива символов той же длины. В этом случае perf stat сообщила о гораздо меньших промахах кеша.
  3. Чтобы повторно проверить, действительно ли я обходит кеш и перехожу в память, я меняю смещение на другое значение в диапазоне оперативной памяти (скажем, 0x80000) и запускаю команду perf для измерения количества промахов в кеше. Путаница здесь заключается в том, что в предыдущем случае почти одинаковое количество промахов кэш-памяти (около 128 200). Я бы ожидал чего-то гораздо меньшего, поскольку я не сделал эту область физического адреса непригодной.

Любые предложения/отзывы об этом, чтобы понять это наблюдение, были бы полезными.

Thanks

+0

Любой может помочь? Действительно любопытно узнать, почему это наблюдение? Благодарю. –

ответ

1

Я думаю, что понял. MAP_PRIVATE с man-страниц говорит, что изменения не отражены в базовом файле.При изменении его на MAP_SHARED и включении записи в/proc/mtrr изменение количества промахов и показов в кэше значительно меняется.