почему физический адрес значения mmap всегда равен нулю? - PullRequest
0 голосов
/ 23 мая 2018

Я написал программу, которая вычисляет физический адрес данного виртуального адреса.Эта программа всегда возвращает 0. Это означает, что конкретная страница не найдена.Почему эта страница недоступна?

Что делает этот код: Этот код создает память файла, а виртуальный адрес с отображением в памяти преобразуется в физический адрес с помощью функции, которую я взял из https://stackoverflow.com/a/28987409/6941772.

#include <sys/mman.h> 
#include <sys/stat.h>
#include <fcntl.h> // O_RDONLY
//#include <stddef.h> // to get NULL definition. NULL not a built in const. 
#include <string.h> // NULL is also defined in string.h, stdlib.h
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include "inttypes.h"

uint64_t vtop(uint64_t vaddr) {
    FILE *pagemap;
    uint64_t paddr = 0;

    unsigned long long int offset = (vaddr / sysconf(_SC_PAGESIZE)) * sizeof(uint64_t);
    uint64_t e;

    // https://www.kernel.org/doc/Documentation/vm/pagemap.txt
    if ((pagemap = fopen("/proc/self/pagemap", "r"))) {
        if (lseek(fileno(pagemap), offset, SEEK_SET) == offset) {
            if (fread(&e, sizeof(uint64_t), 1, pagemap)) {
                if (e & (1ULL << 63)) { // page present ?
                    paddr = e & ((1ULL << 54) - 1); // pfn mask
                    paddr = paddr * sysconf(_SC_PAGESIZE);
                    // add offset within page

                    paddr = paddr | (vaddr & (sysconf(_SC_PAGESIZE) - 1));
                                        printf(" paddr %lu \n", paddr);
                }
                                else {
                                    printf("page not found\n");
                                    }
            }
        }
        fclose(pagemap);
    }

    return paddr;
}

int main() {

    int oflag = O_RDONLY;
    const char *path = "file.json";
    const int fd = open(path, oflag);

    // use stat to find the file size
    struct stat stat;
    int ret = fstat(fd, &stat);

    int mflags = MAP_PRIVATE; // information about handling the mapped data
    int mprot = PROT_READ|PROT_WRITE; // access permissions to the data being mapped 
    size_t size = stat.st_size;
    void *addr = mmap(NULL, size, mprot, mflags, fd, 0);
    printf("virtual addres is %p\n", addr);
    printf("physical addres is %ld\n", vtop((uint64_t)addr));

    return 0;
}

Когда я использую malloc вместо mmap, я получаю физический адрес как 0x670 Какова специальность этого числа?

1 Ответ

0 голосов
/ 24 мая 2018

Я написал программу, которая вычисляет физический адрес данного виртуального адреса.Эта программа всегда возвращает 0.

Для доступа к физическому адресу из /proc/self/pagemap требуется запустить программу с правами суперпользователя (sudo).В противном случае вы все равно сможете открыть /proc/self/pagemap и прочитать с него.Просто физические адреса кажутся нулевыми.Поскольку вы передаете NULL первому параметру mmap, он вернет виртуальный адрес с выравниванием страницы.Таким образом, смещение страницы также равно нулю.Следовательно, vtop вернет ноль.

Когда я использую malloc вместо mmap, я получаю физический адрес как 0x670, что это за специальность этого числа?

При выделении памяти с использованием malloc возвращенный виртуальный адрес может не выравниваться по странице.Поэтому смещение страницы не может быть нулевым.Напечатанное значение 0x670 - это просто смещение страницы, добавленное к физическому адресу, равному нулю.

Вот что вам нужно сделать:

  • Убедитесь, что параметр длины (файлsize) передается в mmap больше нуля (файл не должен быть пустым).В противном случае mmap возвращает -1 с errno, установленным на EINVAL.
  • Независимо от того, имеет ли программа привилегии root, если ни одна из отображенных страниц не была затронута, по умолчанию никакие физические страницы не будутвыделено для них.Программа напечатает page not found.Чтобы избежать этой проблемы, вы можете прочитать один байт (char c = *((char*)addr);) перед вызовом vtop.
  • Теперь, если вы дотронетесь до первой страницы сопоставленной области, но запустили программу без прав root,физический адрес будет нулевым, но смещение страницы может быть нулевым или нет.Так что вы просто получите смещение страницы.Запустите программу с sudo для решения проблемы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...