Member 13861762 Ответов: 2

Как ведет себя 8-битный доступ к памяти при замене замените отображение /dev/mem нормальным выделением памяти


Это код, и он дает ошибку сегментации (ядро)
static uint32_t map_size = 0x08000000;
static uint32_t map_base = 0x18000000;
static uint32_t map_addr = 0x00000000;
static uint64_t cycle_count = 0x1000000;


static char *dev_mem = "/dev/mem";

int main(int argc, char **argv) {
int fd;
uint8_t *buf;
if ((fd = open(dev_mem, O_RDWR | O_SYNC)) == -1) {
    printf("can't open /dev/mem .\n");
    exit(EXIT_FAILURE);
}

buf = (uint8_t *) malloc(sizeof(uint8_t));
if (buf == 0) {
    printf("Can't be mapped. \n");
    exit(EXIT_FAILURE);
} else
    map_addr = (long unsigned) buf;

uint8_t sum = 0;

while (cycle_count-- > 0)
    sum += *buf++;

printf("%u\n", sum);
close(fd);
exit(EXIT_SUCCESS);


return 0;
  }


Что я уже пробовал:

Итак, я наблюдал, как время выполнения ведет себя для различных битовых слов, ниже приведен пример программы, которая читает 8-битное слово. Я хотел проверить, как он ведет себя, когда мы заменяем отображение /dev/mem "нормальным" выделением памяти (то есть malloc/calloc). Но мой код начал давать ошибку сегментации (дамп ядра). Кто-нибудь поможет?

Я новичок в этом, так что извините, если ошибки глупы.

2 Ответов

Рейтинг:
2

Rick York

Внимательно изучите, что происходит в этом коде. Причина этой ошибки для меня очевидна. Начнем с того, что открытый файл/ dev/mem ни для чего не используется. Удалите все ссылки на него, и вы увидите, что код все еще компилируется. Проблема заключается в том, что вы выделяете буфер размером один байт (sizeof(uint8_t)), предполагая, что это 8 бит, назначаете ему указатель, а затем пытаетесь получить доступ к 0x1000000 байтам этого буфера. Единственный способ, который может работать без сбоев, - это процессор с незащищенным плоским адресным пространством. Буфер должен быть не менее 0x1000000 байт, чтобы код выполнялся правильно.

На самом деле, мне кажется, что вы пытаетесь отобразить файл в пространство памяти вашего приложения. Для этого найдите функции MapViewOfFile и CreateFileMapping.


Рейтинг:
1

Jochen Arndt

Вы должны знать, как управляется память в вашей системе (Linux). При звонке malloc(), будет проверено, достаточно ли места в куче приложения для удовлетворения запроса. Если нет, то куча вашей программы будет увеличена, запросив больше памяти из системы. Фактическая куча назначается вашему приложению операционной системой, чтобы оно могло делать с этой памятью все, что угодно. Но доступ к памяти, не назначенной вашему приложению, защищен и приводит к ошибке сегментации.

Вот что происходит здесь, как описано в решении 1: вы выделяете буфер размером 1 байт, но получаете доступ к 0x100000 = 1 МБ.

В то время как доступ к первым байтам этого 1-байтового буфера обычно работает, потому что в куче может быть какая-то оставшаяся (неиспользуемая) память, ошибка сегментации возникает после того, как ваш buf указатель покидает кучу вашего приложения (точнее: покидает диапазон памяти, который был назначен вашему приложению операционной системой).