LINUX.ORG.RU

маппирование CMA области на /dev/mem

 cma,


0

2

Здравствуйте!
Мне нужно выделить 256-512 Мб непрерывной(!) физической памяти и иметь прямой доступ к ней из пространства пользователя.
Для выделения памяти я решил использовать патч CMA.
По моей задумке все должно происходить так:
1. CMA выделят нужное кол-во памяти во время загрузки системы.
2. Парсится вывод CMA патча, который имеет вид, например: «CMA: reserved 256 MiB at 27400000» и из него извлекаются данные: размер CMA области = 256*1024*1024 байта и физический адрес этой области = 0х27400000 (это значение только для моей системы разумеется).
3. Маппирую нужное кол-во байт функцией mmap() в файл /dev/mem с оффсетом = 0х27400000. Естественно, параметр CONFIG_STRICT_DEVMEM отключен.

Все вроде как просто, но следующий код приводит к segmentation fault(объем памяти тут взял = 1Мб):

int file;
void* start;

file=open("/dev/mem", O_RDWR | O_SYNC);

if ( (start = mmap(0, 1024*1024, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0x27400000)) == MAP_FAILED ){
    perror("mmap");
}

for (int offs = 0; offs<50; offs++){
     cout<<((char *)start)[offs];
}

Выводит следующее: mmap: Invalid argument.

Но если в этом коде оффсет поменять на ноль или на многие другие значения (которые я брал из /proc/iomem), то код работает прекрасно и выводит мусор, как и ожидается.
Судя по информации из того же /proc/iomem физический адрес CMA зоны (0х27400000 на моей системе) всегда находится в System RAM. И этот участок система никак не позволяет мне смаппировать.

Подскажите пожалуйста, как можно это сделать?
Заранее спасибо!



Последнее исправление: just_a_student (всего исправлений: 2)

Если это делается на своём железе, то проще нужный memmap в командную строку ядру добавить.

mv ★★★★★
()

Я даже не понимаю, почему ты считаешь, что твой способ должен работать. CMA предназначен для драйверов:

    struct page *dma_alloc_from_contiguous(struct device *dev, int count, unsigned int align);

И зачем тебе непрерывная память в userspace? Если ты говнокодишь userspace-драйвер - лучше не делай этого.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Драйвер (нормальный) будет писать в эту непрерывную память, а пользовательское приложение должно иметь возможность эти данные считать и обработать. Просто объем памяти, в которую будет писать устройство, очень большой (до 512 мб а может и больше), поэтому заморочился с CMA

just_a_student
() автор топика
Ответ на: комментарий от tailgunner

CMA для дайверов, да. Но решил попробовать использовать его лишь частично (только для выделения памяти)

just_a_student
() автор топика
Ответ на: комментарий от just_a_student

Драйвер (нормальный) будет писать в эту непрерывную память,

Устройство, ты имеешь в виду?

а пользовательское приложение должно иметь возможность эти данные считать и обработать.

Тогда просто реализуй у драйвера операцию mmap (заодно сможешь мапить только страницы, заполненные данными).

Просто объем памяти, в которую будет писать устройство, очень большой

Я понял, что mmap у тебя в роли read, но координировать доступ должен драйвер.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от just_a_student

Подсказали правильное решение. В драйвере выдели весь этот непрерывный регион и через char device передай указатель на этот регион посредством реализации функции mmap.

Dead ★★★★
()

Проблема разрешилась отключением параметра CONFIG_X86_PAT. Теперь могу маппировать /dev/mem как мне заблагорассудится!

just_a_student
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.