LINUX.ORG.RU

Работа с физ. памятью


0

0

Есть несколько вопросов по памяти
допустим с помощью malloc я выделяю память:
1) Как узнать её физический адрес
2) как сделать что-бы она не перемещялась и не скидывалась в своп
Всё это необходимо выполнить в User-space программе.OS: linux 2.6.x


А зачем так извращаться в user-space ???

И много ты в такой системе наработаешь, в которой каждая прикладная прога будет говорить - не, мне только фиксированную память в RAM подавайте...

Spectr ★★★
()

Или пиши helper модуль ядра, или пересмотри метод решения задачи.

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

Для DMA надо... Т.е некая прога должна обмениваться данными c pci устройством в режиме DMA. После заворшения операции можно либо скопировать инфу в другой участок памяти, а этот освободить, либо этот участок памяти сделать обычным. Модуль к ядру писать не охота, документацию читать надо, вот я и подумал может есть какой-нибудь другой способ.

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

На что только не готовы програмеры лишь бы доки не читать !

mumg
()

первое невозможно, а второе очень просто:

#include <sys/mman.h>
int mlock(const void *addr, size_t len);

заставляет не сбрасывать в своп память по адресу addr длиной len. 

Например:
  char *ptr = malloc(765); 
  mlock(ptr, 765);

Не-root может блокировать максимум RLIMIT_MEMLOCK байт памяти (возможно, это значение будет нулём - учти). Потом блок можно разблокировать (разрешить свопить) таким образом:
  munlock(ptr, 765);
или
  munlockall();

Кстати, всю уже выделенную память можно заблокировать с 
  mlockall(MCL_CURRENT);
а заставить автоматически блокировать вновь выделяемую память
- с помощью
  mlockall(MCL_FUTURE);

Вот и всё про блокировки памяти. 

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

Большое спасибо.

Но раз первое не выполнимо в User_space, то придётся писать модуль. Поэтому хотелось бы спросить, что можно почитать по этой теме(архитектура ядра, программирование модулей), что-бы было понятым языком написанно.

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

Если вдруг денег не хватит, пиши. Залью в электронном виде (формат .chm)

anonymous
()

А может mmap()-а достаточно?

Возможно устройство поддерживает mmap() на DMA-шной области? Тогда этого достаточно и не нужно писать свой модуль. Ну еще залочить (хотя не всегда нужно), как описали выше, выделенный буфер и будет все ОК. Очень уж эта тема аппаратно-зависимая и нужное решение можно посоветовать только зная спецификацию устройства и реализацию драйверов. Я лично несколько раз сталкивался с ситуацией, когда драйвера устройства, поддерживали доступ к DMA-буферу из юзерспейс через mmap().

anonymous
()
Ответ на: А может mmap()-а достаточно? от anonymous

> Я лично несколько раз сталкивался с ситуацией, когда драйвера 
> устройства, поддерживали доступ к DMA-буферу из юзерспейс через 
> mmap().

Ну так чтоб так было, надо такой драйвер написать :)
Я этим недавно занимался. Прога из user-space мапит DMA-область и 
пишит/читает данные. Если товарища интерисует - могу набросать как
мапить, а остальное - LDD3.

senjy
()
Ответ на: комментарий от platerx

Не уверен, в полной правильности, но пока все хорошо работает.

В user-space вызываю mmap():
dma_buff = (unsigned int *) mmap(0, blkSz, PROT_READ | PROT_WRITE, 
MAP_SHARED, fd, 0);

Ф-ция обработчик вызова mmap() ядре:
static int drv_mmap (struct file *filp, struct vm_area_struct *vma) {
  unsigned long off;
  unsigned int *virt_rg;

  off = vma->vm_pgoff << PAGE_SHIFT;
  vma->vm_flags |= VM_RESERVED;
  if(remap_pfn_range(vma, vma->vm_start,
     page_to_pfn(virt_to_page(dma_addr)),vma->vm_end - vma->vm_start,
     vma->vm_page_prot)) {return -EAGAIN;}
  return 0;
} 

Здесь, dma_addr - виртуальный адрес DMA-буфера, который предварительно
получаю

dma_addr =  (unsigned int*)dma_alloc_coherent( &dev, Size, 
             &dma_buff_phys, GFP_KERNEL);

dma_buff_phys - физический адрес буфера, который потом скормишь
контроллеру DMA.

Ну в общем все. 

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